组合模式
组合模式,是为了解决整体和部分的一致对待的问题而产生的,要求这个整体与部分有一致的操作或行为。部分和整体都继承与一个公共的抽象类,这样,外部使用它们时是一致的,不用管是整体还是部分,使用一个方法即可遍历整体中的所有的部分。就像一个树形结构一样。
如下面的类图,client的只需要使用Component即可,无须关心到底是Leaf还是Composite。
这里有两种情况,add函数对于Leaf来说是没有必要的,所以一种办法就是在Leaf的add实现中什么都不写。
还一种办法就是将add方法挪到Composite中,让外部使用Composite和Component。但这样的缺点就是暴露了Composite,客户端必须知道Composite才能完成操作,好处Leaf不用产生多余的方法了。
常用场景
常用于组织结构,产品结构之类的整体和部分的结构。例如图形由很多直线构成,直线由点构成,这就是整体和部分的关系。如果采用组合模式,只需要使用一个draw方法即可按遍历的方式画出所有的点,最终呈现出来的就是图形。
优点
1.隐藏了整体和部分,让外部依赖于抽象,简化了代码。
缺点
1.要求必须有一致的行为。
2.处于同一个Composite的Leaf与Leaf之间难以传递数据。
C++实现
1 #ifndef _COMPONENT_H_ 2 #define _COMPONENT_H_ 3 4 #include <vector> 5 #include <stdio.h> 6 7 using namespace std; 8 9 class Component 10 { 11 public: 12 Component(){}; 13 virtual ~Component(){}; 14 15 virtual void operation() = 0; 16 }; 17 18 19 20 class Leaf: public Component 21 { 22 public: 23 Leaf(){}; 24 ~Leaf(){}; 25 26 void operation(); 27 }; 28 29 30 class Composite: public Component 31 { 32 public: 33 Composite(){}; 34 ~Composite(){}; 35 36 void add(Component*); 37 void operation(); 38 39 private: 40 vector<Component*> m_leafs; 41 }; 42 43 #endif
1 #include "Component.h" 2 3 4 5 void Leaf::operation() 6 { 7 fprintf(stderr, "----operation leaf "); 8 } 9 10 11 void Composite::add(Component* c) 12 { 13 m_leafs.push_back(c); 14 } 15 16 17 18 void Composite::operation() 19 { 20 fprintf(stderr, "operation Composite "); 21 vector<Component*>::iterator comIter = m_leafs.begin(); 22 23 for (; comIter != m_leafs.end(); comIter++) 24 { 25 fprintf(stderr, "----"); 26 (*comIter)->operation(); 27 } 28 }
1 #include "Component.h" 2 3 4 int main() 5 { 6 Component* leaf1 = new Leaf(); 7 Component* leaf2 = new Leaf(); 8 9 Composite* composite1 = new Composite(); 10 composite1->add(leaf1); 11 composite1->add(leaf2); 12 13 Composite* composite2 = new Composite(); 14 composite2->add(composite1); 15 16 composite2->operation(); 17 return 0; 18 }
1 g++ -o client client.cpp Component.cpp
运行结果