设计模式之十五:组合模式(Composite)
2015-06-09 19:16
459 查看
组合模式:
将对象组合成树形结构来表示部分与整体的关系。组合模式让客户能将单个对象和组合对象统一对待。
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
感觉这是一个很有意思的模式,递归的思路在这里面也得到了体现。如果考虑的业务模型中存在树形结构可以考虑这个模式。
UML图:
主要包括:
Component(DrawingElement):为组合模式中的对象声明了一个接口;实现了一些缺省的行为;声明了一些访问子对象的接口。
Leaf(PrimitiveElement):代表组合模式中的叶节点。叶节点不再包含其它节点。
Composite(CompositeElement):定义有组合对象的行为;包含其它组合对象;实现了对子对象操作的一些接口。
C++代码实现如下:
这里也复习了一下stl容器删除操作。如果提供的是指针,直接进行erase即可,但是如果要删除具有特定值的对象,可以按照下列规则:
对于在内存中连续的顺序容器,如vector,deque,string推荐erase-remove的方法(这种方法对list也可用,但是list有更高效的方法)
对于list而言,可以使用list的成员函数remove,这样效率会更高一些:
对于关联容器,可以直接调用erase函数
执行输出:
下面是一个具体的绘图程序的例子:
Component为DrawingElement,为绘图元素
Leaf为PrimitiveElement,基本的绘图元素,不能再包含其它绘图元素
Composite为CompositeElement
实际上上面的结构是UI中各种元素的简化版,UI中存在各种基本元素,比如按钮,文本框,也包括组合元素,比如各种布局控件,对话框等。它们应该是组合模式一个很好的应用。
UML类图:
C++实现代码:
执行输出:
将对象组合成树形结构来表示部分与整体的关系。组合模式让客户能将单个对象和组合对象统一对待。
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
感觉这是一个很有意思的模式,递归的思路在这里面也得到了体现。如果考虑的业务模型中存在树形结构可以考虑这个模式。
UML图:
主要包括:
Component(DrawingElement):为组合模式中的对象声明了一个接口;实现了一些缺省的行为;声明了一些访问子对象的接口。
Leaf(PrimitiveElement):代表组合模式中的叶节点。叶节点不再包含其它节点。
Composite(CompositeElement):定义有组合对象的行为;包含其它组合对象;实现了对子对象操作的一些接口。
C++代码实现如下:
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; class Component { public: Component(string n=string("")):name(n) { } virtual void add(Component * c) { } virtual void removeComponent(Component * c) { } virtual Component* getChild(int index) { } virtual void display(int depth)=0; protected: string name; }; class Leaf:public Component { public: Leaf(string str=""):Component(str) { } void display(int depth) { string str(depth+2,'-'); std::cout<<str<<name<<std::endl; } }; class Composite:public Component { public: Composite(string str=""):Component(str) { } void add(Component* c) { children.push_back(c); } void removeComponent(Component *c) { children.erase( remove(children.begin(),children.end(),c),children.end()); } void display(int depth) { string str(depth+2,'-'); std::cout<<str<<name<<std::endl; vector<Component*>::iterator iter=children.begin(); for(;iter!=children.end();iter++) (*iter)->display(depth+1); } Component* getChild(int index) { return children[index]; } private: vector<Component *> children; }; int main() { std::cout<<"组合模式例子"<<std::endl; Component *root=new Composite("root"); Component * etc=new Composite("etc"); Component * mnt=new Composite("mnt"); root->add(etc); root->add(mnt); Component * txt1=new Leaf("txt1"); Component *txt2=new Leaf("txt2"); etc->add(txt1); etc->add(txt2); root->display(0); std::cout<<std::endl<<std::endl<<"after erase"<<std::endl; etc->removeComponent(txt1); root->display(0); return 0; }
这里也复习了一下stl容器删除操作。如果提供的是指针,直接进行erase即可,但是如果要删除具有特定值的对象,可以按照下列规则:
对于在内存中连续的顺序容器,如vector,deque,string推荐erase-remove的方法(这种方法对list也可用,但是list有更高效的方法)
vector<int> c; //注意remove是<algorithm>中的函数 c.erase( remove(c.begin(),c.end(), 25), c.end());
对于list而言,可以使用list的成员函数remove,这样效率会更高一些:
list<int> list_int; .... list_int.remove(25);
对于关联容器,可以直接调用erase函数
map<int, int> mapContainer; ... mapContainer.erase(25);
执行输出:
下面是一个具体的绘图程序的例子:
Component为DrawingElement,为绘图元素
Leaf为PrimitiveElement,基本的绘图元素,不能再包含其它绘图元素
Composite为CompositeElement
实际上上面的结构是UI中各种元素的简化版,UI中存在各种基本元素,比如按钮,文本框,也包括组合元素,比如各种布局控件,对话框等。它们应该是组合模式一个很好的应用。
UML类图:
C++实现代码:
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; class DarawingElement { public: DarawingElement(string n=string("")):name(n) { } virtual void add(DarawingElement * c) { } virtual void removeDarawingElement(DarawingElement * c) { } virtual DarawingElement* getChild(int index) { } virtual void display(int depth)=0; protected: string name; }; class PrimitiveElement:public DarawingElement { public: PrimitiveElement(string str=""):DarawingElement(str) { } void display(int depth) { string str(depth+2,'-'); std::cout<<str<<name<<std::endl; } }; class CompositeElement:public DarawingElement { public: CompositeElement(string str=""):DarawingElement(str) { } void add(DarawingElement* c) { children.push_back(c); } void removeElement(DarawingElement *c) { children.erase( remove(children.begin(),children.end(),c),children.end()); } void display(int depth) { string str(depth+2,'-'); std::cout<<str<<"+"<<name<<std::endl; vector<DarawingElement*>::iterator iter=children.begin(); for(;iter!=children.end();iter++) (*iter)->display(depth+1); } private: vector<DarawingElement *> children; }; int main() { std::cout<<"具体的组合模式,画图程序例子"<<std::endl; DarawingElement *pic=new CompositeElement("picture"); DarawingElement * redLine=new PrimitiveElement("red line"); DarawingElement * blueCircle=new PrimitiveElement("blueCircle"); DarawingElement * greenBox=new PrimitiveElement("green box"); pic->add(redLine); pic->add(blueCircle); pic->add(greenBox); DarawingElement * twoCircles=new CompositeElement("two circles"); DarawingElement * blackCircle=new PrimitiveElement("black circle"); DarawingElement * whiteCircle=new PrimitiveElement("white Circle"); twoCircles->add(blackCircle); twoCircles->add(whiteCircle); pic->add(twoCircles); pic->display(1); return 0; }
执行输出:
相关文章推荐
- 软件工程的基本概念
- VHDL之FSM
- Android(java)学习笔记106-1:类的加载器(反射机制)
- 第4题
- char* str和char str[]的区别
- 快速排序算法
- Linux——RPM包管理
- Unity教程之手把手教你实现动画Animation
- android Graphics:canvas变换与操作
- 1246 罐子和硬币
- NSURLCache
- 一场由股票提醒助手插件引发的血案——浅入浅出 jquery autocomplete
- Action Service Dao三层的功能划分
- jQuery 参考手册 - Ajax
- CODE[VS] 1006 等差数列
- 第七章
- 位运算基本概念及简单运用
- CODE[VS] 1006 等差数列
- easyui textarea IE8中无法换行
- TCP通信客户端简单示例