概念:將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得用戶對(duì)單個(gè)對(duì)象和組合的使用具有一致性。
注意:組合模式有透明組合模式和安全組合模式。透明組合模式是將Addordinate和GetSubordinate這兩個(gè)函數(shù)也抽象到CCorpNode基類里,這增加了操作葉子節(jié)點(diǎn)的難度,更易出現(xiàn)邏輯問(wèn)題。所以盡量使用安全模式。
針對(duì)DrawingSystem中的基類Shape和各個(gè)子類Line、Rec、Circle,請(qǐng)使用某種模式來(lái)支持更復(fù)雜的形狀,該復(fù)雜形狀是各個(gè)形狀的自由組合。使用松耦合面向?qū)ο笤O(shè)計(jì)方法和思想,可使用偽碼表示設(shè)計(jì)。
經(jīng)過(guò)思考,認(rèn)為組合模式最適合這題目。
可以構(gòu)想將這些子類作為葉子,而葉子可以在掛載在同一個(gè)節(jié)點(diǎn)上,那么這個(gè)節(jié)點(diǎn)便是復(fù)雜形狀。由此,按照這個(gè)思路,完成了作業(yè)
//使用設(shè)計(jì)模式中的組合模式
//Shape為抽象基類
//ShapeNode 為節(jié)點(diǎn)類
//其他基本形狀為L(zhǎng)eaf。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
class Shape
{
public:
virtual ~Shape(){}
virtual void Add(Shape *) = 0; //加載元素
virtual void Remove(unsigned int) = 0; //移除指定位置元素
virtual void Clear() = 0; //清空元素
virtual void GetInfo() = 0; //獲取形狀信息
virtual void Process() = 0;
};
class Line :public Shape
{
private:
string info = "Line";
public:
Line() { }
void Add(Shape *pComponent){}
void Remove(unsigned int num){}
virtual void Clear() {}
void GetInfo()
{
cout <<info << endl;
}
void Process()
{
//...
}
};
class Circle :public Shape
{
private:
string info = "Circle";
public:
Circle() { }
void Add(Shape *pComponent){}
void Remove(unsigned int num){}
virtual void Clear() {}
void GetInfo()
{
cout << info << endl;
}
void Process()
{
//...
}
};
class Rec :public Shape
{
private:
string info = "Rec";
public:
Rec() { }
void Add(Shape *pComponent){}
void Remove(unsigned int num){}
virtual void Clear() {}
void GetInfo()
{
cout <<info << endl;
}
void Process()
{
//...
}
};
class ShapeNode:public Shape
{
private:
static int cnt;//用于統(tǒng)計(jì)有多少個(gè)節(jié)點(diǎn)
int num;
vector<Shape *> shapeNode;
public:
typedef vector<Shape *>::iterator ShapeLiterator;
ShapeNode(){ ++cnt; num = cnt; }
~ShapeNode()
{
ShapeLiterator it = shapeNode.begin();
while (it != shapeNode.end())
{
if (*it != NULL)
{
delete *it;
*it = NULL;
}
shapeNode.erase(it);
it = shapeNode.begin();
}
}
void Add(Shape *pComponent)
{
shapeNode.push_back(pComponent);
}
void Remove(unsigned int num)
{
if (num < shapeNode.size())
{
ShapeLiterator it = shapeNode.begin();
shapeNode.erase(it + num);
}
else
{
cerr << "the num is OUT OF LIMIT, please Input again" << endl;
}
}
void Clear()
{
if (!shapeNode.empty())
{
shapeNode.clear();
}
}
void GetInfo()
{
if (!shapeNode.empty())
{
cout <<"I'm No."<<num<<" ShapeNode, I have "<<shapeNode.size()<< " Shapes:" << endl;
for (ShapeLiterator it = shapeNode.begin(); it != shapeNode.end();it++)
{
(*it)->GetInfo();
}
}
else
{
cout << "I'm No." << num << " ShapeNode, I have no Shapes!" << endl;
}
}
void Process()
{
//...
}
};
int ShapeNode::cnt = 0;
void Process(Shape &shape)
{
shape.Process();
}
int main()
{
//創(chuàng)建第一個(gè)多組合形狀及其元素
Shape *pShape1 = new ShapeNode();
Shape *pLineLeaf1 = new Line();
Shape *pLineLeaf2 = new Line();
Shape *pCircleLeaf1 = new Circle();
//加載元素
pShape1->Add(pLineLeaf1);
pShape1->Add(pLineLeaf2);
pShape1->Add(pCircleLeaf1);
pShape1->GetInfo();
cout << endl;
//創(chuàng)建第二個(gè)多組合形狀及其元素
Shape *pShape2 = new ShapeNode();
Shape *pRecLeaf1 = new Rec();
Shape *pCircleLeaf2 = new Circle();
Shape *pRecLeaf2 = new Rec();
//加載元素
pShape2->Add(pRecLeaf1);
pShape2->Add(pCircleLeaf2);
pShape2->Add(pRecLeaf2);
pShape2->GetInfo();
cout << endl;
//測(cè)試刪除指定元素函數(shù)
pShape2->Remove(1);
pShape2->GetInfo();
pShape2->Remove(4);
//測(cè)試清空元素函數(shù)
pShape2->Clear();
cout << endl;
pShape2->GetInfo();
Process(pShape1);
//...
}