Linux C++ 065-设计模式之组合模式
本节关键字:Linux、C++、设计模式、组合模式
相关库函数:
概念
组合模式(Composite Pattern),又叫做部分-整体模式,使得用户对单个对象和组合对象的使用具有一致性。它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
角色说明
Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
代码示例
// 将对象组合成树形结构以表示“部分——整体”的结构层次,使得客户端对单个对象或者组合对象的使用具有一致性。(在word复制一个字、一行文字、一段文字都是一样的操作)
// 把组合模式想象成一棵大树,大树分为树枝和树叶两部分,树枝可以长树枝和树叶,但是树叶不能再张别的东西。
//
// 组合模式的适用情况:
// 希望表示对象的“部分——整体”的结构层次
// 希望客户端忽略单个对象和组合对象的不同,客户端统一处理的是组合对象
//
class Component
{
public:
string name;
Component(string name) {
this->name = name;
}
virtual void add(Component*) = 0;
virtual void remove(Component*) = 0;
virtual void display(int) = 0;
};
// 叶子节点类,叶节点没有子节点
class Leaf : public Component
{
public:
Leaf(string name) : Component(name) {}
void add(Component* c) {
cout << "leaf cannot add" << endl;
}
void remove(Component* c) {
cout << "leaf cannot remove" << endl;
}
void display(int depth) {
string str(depth, '-');
str += name;
cout << str << endl;
}
};
// 枝节点类
class Composite : public Component
{
private:
vector<Component*> component;
public:
Composite(string name) : Component(name) { }
void add(Component* c) {
component.push_back(c);
}
void remove(Component* c) {
vector<Component*>::iterator iter = component.begin();
while (iter != component.end()) {
if (*iter == c) {
component.erase(iter); // 当删除iter所指向的元素后,iter指向原删除元素的下一个位置,如果删除的是最后一个元素,iter指向末尾component.end()
return; // 为了防止删除的是最后一个位置,再执行iter++时出错,我们在这里删除元素后直接返回
}
iter++;
}
}
void display(int depth) {
string str(depth, '-');
str += name;
cout << str << endl;
vector<Component*>::iterator iter = component.begin();
while (iter != component.end()) {
(*iter)->display(depth + 2);
iter++;
}
}
};
int main_Component()
{
Component* p = new Composite("LI");
Leaf* l = new Leaf("WANG");
// 增加树叶
p->add(l);
p->add(new Leaf("QIANG"));
Component* sub = new Composite("HU");
sub->add(new Leaf("WANG"));
sub->add(new Leaf("MING"));
sub->add(new Leaf("LIU"));
// 增加树枝
p->add(sub);
p->display(0);
cout << "****************" << endl;
sub->display(2);
cout << "****************" << endl;
// 删除树枝
p->remove(sub);
p->display(0);
return 0;
}
/* 运行结果:
LI
--WANG
--QIANG
--HU
----WANG
----MING
----LIU
*******
--HU
----WANG
----MING
----LIU
*******
LI
--QIANG
--HU
----WANG
----MING
----LIU
*******
LI
--QIANG
*/
// 组合模式完美的使用了面向对象里面的多态性,叶子类和树枝类都继承了一个抽象基类(Component)
// 叶子类:只能进行显示
// 树枝类:可以增加、删除、显示叶子或者树枝对象,传入的参数都是抽象基类的指针, 因为可以在运行的过程中进行动态绑定,来决定是操作叶子对象还是操作树枝对象
// 客户端:实例化抽象基类的对象指针,该指针指向树枝类的对象;可以通过该指针访问树枝类的对象,对其进行增加叶子对象或者数值对象,删除叶子对象或者数值对象
//