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; }
|