composite pattern
DESCRIPTION
Here goTRANSCRIPT
![Page 2: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/2.jpg)
Structural pattern
Compose objects into a tree structure to represent part-whole relationship
![Page 3: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/3.jpg)
An abstract class represents both primitives and containers
The client handles both the primitives and their containers in the same fashion
![Page 4: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/4.jpg)
Tree structure of the Composite Pattern
![Page 5: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/5.jpg)
Applicability
To represent part-whole hierarchy
To make the client ignorant about whether it is interacting with an individual object or a composite object
![Page 6: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/6.jpg)
Class Diagram
![Page 7: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/7.jpg)
Example – base class Shapeclass Shape{public:
Shape(){}virtual void Add(unsigned int id){
throw LeafClassTypeException();};virtual void Remove(unsigned int id){};
//leaf classes will not override it..however, it will be overridden by the composite class.virtual Shape* GetChild(unsigned int id){
throw LeafClassTypeException();};
//Using this reference the "Chain of Responsibility" can be implementedvirtual Shape* GetParentOfComponent(){
return ParentOfComponent;};
virtual void SetParentOfComponent(Shape* s){
ParentOfComponent = s;}
virtual void Display(){};
virtual Shape* FindItem(unsigned int id); //implementation afterwards
virtual ~Shape(){};
protected:Shape* ParentOfComponent;unsigned int resource_id;
};
![Page 8: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/8.jpg)
Iterator and the FindItem functiontypedef map <unsigned int, Shape*, less<unsigned int> > theMap;
theMap Resource_Map;theMap::iterator theIterator;
Shape* Shape::FindItem(unsigned int id){
theIterator = Resource_Map.begin();while (theIterator != Resource_Map.end()){theIterator = Resource_Map.find(id);Shape* s = (*theIterator).second;theIterator++;return s;}
return NULL;}
![Page 9: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/9.jpg)
A leaf class - Pointclass Point : public Shape{public:
Point():x_Coord(0),y_Coord(0){}Point(int x, int y):x_Coord(x), y_Coord(y){}Point(const Point& p){
x_Coord = p.x_Coord;y_Coord = p.y_Coord;
}Point& operator = (const Point& p){
x_Coord = p.x_Coord;y_Coord = p.y_Coord;
return *this;}
virtual void Display(){
cout<<"X Coordinate is:"<<x_Coord<<endl;cout<<"Y Coordinate is:"<<y_Coord<<endl;
}
int X_COORD() {
return x_Coord;}
int Y_COORD(){
return y_Coord;}
virtual ~Point(){}private:
int x_Coord;int y_Coord;
};
![Page 10: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/10.jpg)
A leaf class – line – a final class as well//class Line is working as a leaf class.. Lets implement it as a final classclass Line : public Shape{private:
//private constructorLine(unsigned int id):begin(0,0),end(0,0){
resource_id = id;Resource_Map.insert(theMap::value_type(resource_id,(Shape*)this));
}//private constructorLine(unsigned int id, Point a, Point b):begin(a),end(b){
resource_id = id;Resource_Map.insert(theMap::value_type(resource_id,(Shape*)this));
}//private copy constructorLine(const Line& in){ }//private assignment operatorLine& operator=(const Line& in){ }
public:virtual void Display(){
cout<<"Begining point is:";begin.Display();
cout<<"End Point is:";end.Display();
}static Line* CreateLine(unsigned int id, Point a, Point b){
return new Line(id,a,b);}
virtual ~Line(){}private:
Point begin;Point end;
};
![Page 11: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/11.jpg)
A leaf class – rectangle – a final class as wellclass Rectangle : public Shape{private:
//private constructorRectangle(unsigned int id, Point& p, int width, int height){
top_left = p;top_right = Point(p.X_COORD() + width, p.Y_COORD());bottom_left = Point(p.X_COORD() , p.Y_COORD() + height); bottom_right = Point(p.X_COORD() + width, p.Y_COORD() + height);resource_id = id;Resource_Map.insert(theMap::value_type(resource_id,(Shape*)this));
}//private copy constructorRectangle(const Rectangle& in){ }
//private assignment operatorRectangle& operator=(const Rectangle& in) { }
public:static Rectangle* CreateRectange(unsigned int id, Point& p, int width, int height){
return new Rectangle(id, p, width, height);
}virtual ~Rectangle(){}virtual void Display(){
cout<<"The four vertices are:"<<endl;cout<<"Top Left :" ;
top_left.Display();cout <<"Top Right :";
top_right.Display();cout<<"Bottom Left :";
bottom_left.Display();cout<<"Bottom Right :";
bottom_right.Display();
}
//Attributesprivate:
Point top_left;Point top_right;Point bottom_left;Point bottom_right;
};
![Page 12: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/12.jpg)
A composite class - pictureclass Picture : public Shape{public:
Picture(unsigned int id){
resource_id = id;Resource_Map.insert(theMap::value_type(resource_id,(Shape*)this));
}virtual void Display(){
vector<Shape*>::iterator p = Components.begin();while (p != Components.end()){
(*p)->Display();p++;
}}
//Adds the component with the resource id equal to the passed parametervirtual void Add (unsigned int id){
Shape* s = FindItem(id);
Components.push_back(s);
s->SetParentOfComponent(this);
}
![Page 13: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/13.jpg)
Class Picture ... contd...//removes the component from the list with the resource_id equal to the parameter passed
virtual void Remove(unsigned int id){
Shape* s = FindItem(id);vector<Shape*>::iterator p = Components.begin();int pos = 0;while (p != Components.end()){
if(Components.at(pos) == s)break;
pos++;p++;
}Components.erase(p);s->SetParentOfComponent(NULL);
}
![Page 14: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/14.jpg)
Class Picture ... contd...//will return the chile having the id equal to the passed value.
virtual Shape* GetChild (unsigned int id){
return FindItem(id);}
virtual ~Picture(){
vector<Shape*>::iterator p = Components.begin();
int pos = 0;while (p != Components.end()){
delete(Components.at(pos));p++;pos++;
}
Components.clear();}
private:vector<Shape*> Components;
};
![Page 15: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/15.jpg)
The client - main()void main(){
Point p1(10,20);Point p2(30,40);Point p3(50,60);Point p4(70,80);Point p5(100,110);Point p6(150,200);Line* l1 = Line::CreateLine(ID_LINE1,p1,p2);try{l1->Add(0);}catch(LeafClassTypeException& e){
e.printerrormsg();}Line* l2 = Line::CreateLine(ID_LINE2,p3,p4);Line* l3 = Line::CreateLine(ID_LINE3,p5,p6);
Rectangle* r1 = Rectangle::CreateRectange(ID_RECTANGLE1, p1, 50,25);
Shape* p = new Picture(ID_PICTURE);p->Add(ID_LINE1);p->Add(ID_LINE2);p->Add(ID_LINE3);p->Add(ID_RECTANGLE1);
(p->GetChild(ID_RECTANGLE1))->Display();
p->Remove(ID_RECTANGLE1);
p->Display();
cout<<p<<endl;
cout<<l1->GetParentOfComponent()<<endl;
delete p;
}
![Page 16: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/16.jpg)
The helper exception class
class LeafClassTypeException{public:
void printerrormsg(){
cout<<"This is a leaf class"<<endl;}
};
![Page 17: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/17.jpg)
Implementation Details
Every component is identifiable through its resource id
Whenever we create an object (leaf or composite object), it creates a key pair of the id and the pointer to that object and pushes this key into a MAP, from which we can easily search for that component in later times through its resource id
![Page 18: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/18.jpg)
Implementation details
The leaf classes, namely Line and Rectangle have been implemented as final classes by making their constructors, copy constructors and assignment operators private and providing static member functions to create them.
![Page 19: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/19.jpg)
Issues
GetParentofComponent can be used to traverse the tree hierarchy
We have to make sure that any child can have a composite object as its parent
No child can have another child if its a leaf
Whenever a leaf class tries to add a child it throws the LeafClassException
![Page 20: Composite Pattern](https://reader038.vdocuments.us/reader038/viewer/2022100507/558fc7ab1a28ab7a4e8b4769/html5/thumbnails/20.jpg)
Issues
Add and Remove functions have been defined in the Root class.
For the leaf classes these just throw exceptions
However it helps the client to treat leaf and composite objects uniformly