概念:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合的使用具有一致性。
注意:组合模式有透明组合模式和安全组合模式。透明组合模式是将Addordinate和GetSubordinate这两个函数也抽象到CCorpNode基类里,这增加了操作叶子节点的难度,更易出现逻辑问题。所以尽量使用安全模式。
针对DrawingSystem中的基类Shape和各个子类Line、Rec、Circle,请使用某种模式来支持更复杂的形状,该复杂形状是各个形状的自由组合。使用松耦合面向对象设计方法和思想,可使用伪码表示设计。
经过思考,认为组合模式最适合这题目。
可以构想将这些子类作为叶子,而叶子可以在挂载在同一个节点上,那么这个节点便是复杂形状。由此,按照这个思路,完成了作业
//使用设计模式中的组合模式
//Shape为抽象基类
//ShapeNode 为节点类
//其他基本形状为Leaf。
#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;//用于统计有多少个节点
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()
{
//创建第一个多组合形状及其元素
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;
//创建第二个多组合形状及其元素
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;
//测试删除指定元素函数
pShape2->Remove(1);
pShape2->GetInfo();
pShape2->Remove(4);
//测试清空元素函数
pShape2->Clear();
cout << endl;
pShape2->GetInfo();
Process(pShape1);
//...
}