Design Pattern--Composite Pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// composite.cpp : Defines the entry point for the console application.
//

#include<iostream>
#include<string>
#include<vector>

namespace pattern{
/// this pattern is composite pattern.
/// in this pattern, it like a tree to call the leaves function.
/// so there is an entry of high level (Graph), and each class has a function called "Draw"
/// the composite class is "Picture".
/// and the leaves are "Line" and "Point".
/// This pattern is combine many objects together which have same functions
/// and have level structures .
/// And the composite class is like a manager.
/// It has the same function also.
/// Benefits of this pattern is : outer class will never know the composite relationship;
/// outer class will deal the composite class only, not all of innerclass. and composite class
/// and inner class have same functions or level structures.
/// Do you think the composite class like a facade in facade pattern?
#ifndef GRAPH_H
#define GRAPH_H

class Graph{
protected:
std::string name;

public:
Graph(std::string name):name(name){std::cout<<"graph "<<name<<" construct"<<std::endl;}

virtual void Draw()=0;
virtual ~Graph(){std::cout<< "graph "<<name<< " destroy"<<std::endl;};
};
#endif

#ifndef PICTURE_H
#define PICTURE_H
class Picture:public Graph{
private:
std::vector<Graph*> list;
public:
Picture(std::string name):Graph(name){std::cout<<"Picture "<<name<<" construct!"<<std::endl;}
virtual void Add(Graph*);
virtual void Remove(Graph*);
virtual void Draw();
~Picture();
};

#endif
Picture::~Picture(){
list.clear();
std::cout<<"Picture destroy!"<<std::endl;
}
void Picture::Add(pattern::Graph * g){
list.push_back(g);
}
void Picture::Remove(pattern::Graph *g){
std::vector<Graph*>::iterator i=list.begin();
while(i!=list.end()){
if(g==*i){
list.erase(i);
break;
}
i++;
}
}
void Picture::Draw(){
std::vector<Graph*>::iterator i=list.begin();
while(i != list.end()){
(*i)->Draw();
i++;
}
}

#ifndef SHAPE_H
#define SHAPE_H
/// Shape class is parent class of "Line" and "Point"
class Shape:public Graph{
public:
virtual void Draw()=0;
Shape(std::string name):Graph(name){std::cout<<"Shape construct!"<<std::endl;}
virtual ~Shape(){std::cout<<"Shape destroy!"<<std::endl;}

};

#endif

#ifndef POINT_H
#define POINT_H
class Point:public Shape{
public:
Point(std::string name):Shape(name){std::cout<<"Point construct!"<<std::endl;}
~Point(){std::cout<<"Point destroy!"<<std::endl;}
virtual void Draw();

};
#endif
void Point::Draw(){
std::cout<<"Draw a point!"<<std::endl;
}

#ifndef LINE_H
#define LINE_H
class Line: public Shape{
public:
Line(std::string name):Shape(name){std::cout<<"Line construct!"<<std::endl;}
~Line(){std::cout<<"Line destroy!"<<std::endl;}
virtual void Draw();
};

#endif
void Line::Draw(){
std::cout<<"Draw a line!"<<std::endl;
}
}

int main()
{
pattern::Line l ("line");
pattern::Point p1 ("point 1");
pattern::Point p2("point 2");
pattern::Picture pic("Picture");
pic.Add(&l);
pic.Add(&p1);
pic.Add(&p2);

pic.Draw();
// if you want destroy some shape, remove them first.
pic.Remove(&p1);
p1.~Point();
pic.Draw();
return 0;
}