组合模式之C++实现

来源:互联网 发布:java interface与抽象 编辑:程序博客网 时间:2024/05/22 03:51

说明:本文仅供学习交流,转载请标明出处,欢迎转载!

       组合模式(Composite)也叫部分-整体模式,是一种非常实用的设计模式,当我们发现需求中系统体现的是整体与局部的层次关系,并且用户希望将组合对象单个对象一致性对待,这个时候“组合模式”的作用可以得到淋漓尽致地发挥了。

        接触过Linux的人都知道Linux的文件系统采用的一种树状的层次结构,在Linux系统中,目录和普通文件都被系统视为文件,而目录内又可以包含普通文件,这样Linux的文件系统就是以这种递归的方式定义。如果我们想描述这样的数据结构,可以考虑采用组合模式。

       组合模式的定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

        从上面的定义我们可以得出组合模式的两大特点:

        1.从模式结构本身来看:模式本身体现的是一种整体与部分的层次结构关系;

        2.从用户的角度(客户端)分析:整体(分支结点)与部分(叶子结点)具有相同的接口,被形态上没有差别。

       组合模式的结构


       本图来自《大话设计模式》

        举例

        下图是一种组合模式的举例:


       C++实现代码(针对以上面的举例)

#include<iostream>#include<string>#include<list>using namespace std;class Component//抽象类,用户通过该接口来访问其子部件{protected:string name;public:Component(){}Component(string str):name(str){};virtual void Add(Component*)=0;//增加子部件virtual void Remove(Component*)=0;//删除子部件virtual void Display(int depth)=0;//遍历结点,depth表示结点的深度};class Leaf:public Component{public:Leaf(string name):Component(name){}//调用基类的构造函数初始化派生类的基类部分void Add(Component* c){cout<<"不能向叶子结点添加部件!"<<endl;}void Remove(Component* c){cout<<"不能从叶子结点删除部件!"<<endl;}void Display(int depth){cout<<string(depth,'-')<<name<<endl;}};class Composite:public Component//添加分支结点(即非叶子结点){private:list<Component*> child;//孩子public:Composite(){}//基类Component调用其默认的构造函数Composite(string name):Component(name){}void Add(Component *c){child.push_back(c);}void Remove(Component *c){child.remove(c);}void Display(int depth){cout<<string(depth,'-')<<name<<endl;list<Component*>::iterator iter=child.begin();while(iter!=child.end()){(*iter)->Display(depth+1);//递归遍历iter++;}}}; int main(){Composite root("root");/****添加root的孩子结点pA****/Leaf *pA=new Leaf("Leaf A");root.Add(pA);/****添加root的孩子结点pB***/Leaf *pB=new Leaf("Leaf B");//添加root的孩子pBroot.Add(pB);/****添加root的分支结点comp***/Composite *comp1=new Composite("Composite X");Leaf *pXA=new Leaf("Leaf XA");Leaf *pXB=new Leaf("Leaf XB");root.Add(comp1);/***添加comp1的分支结点comp2****/Composite *comp2=new Composite("Composite XY");    Leaf *pXYA=new Leaf("Leaf XYA");Leaf *pXYB=new Leaf("Leaf XYB");comp2->Add(pXYA);comp2->Add(pXYB);comp1->Add(comp2);/***添加root的孩子结点pC和pD****/Leaf *pC=new Leaf("Leaf C");Leaf *pD=new Leaf("Leaf D");root.Add(pC);root.Add(pD);    cout<<"显示当前树的结果:"<<endl;root.Display(1);/****删除root的孩子结点pD***/cout<<"显示删除结点D后的结果:"<<endl;root.Remove(pD);//注意,只是从树中删除了,并没有从堆中删除root.Display(1);/***释放所申请的堆内存空间,C++的麻烦就在此呀,哈哈***/delete pA;delete pB;delete comp1;delete pC;delete pD;delete pXA;delete pXB;delete comp2;delete pXYA;delete pXYB;return 0;}

       测试结果

      

参考资料:

[1]《大话设计模式》

[2]《设计模式之禅》

[3]《HeadFirst设计模式》


0 0
原创粉丝点击