组合模式把相同基类型的对象组合到树状结构中,父节点包含同类型的子节点
形成"部分-整体"的层次结构
部分-整体:既包含对象的组合又包含作为叶子节点的单个对象的一种层次机构
每个组合体包含其它节点,可以使叶子节点或者其它组合体,这种关系在
层次结构中递归重复,每个组合或者叶子节点具有相同的基类,同样的
操作可以应用他们中的每一个,不必再客户端做类型检查。
Objective-C中使用UIView实现组合模式,UIView的实例可以包含其它实例
形成统一的树形结构,让客户端对单个UIView对象和UIView的组合统一对待
UIView对象只能有一个父视图,可以有多个子视图
类图如下:
模拟UIView绘图过程:
#import <set>
#import <iostream>
using namespace::std;
class IUIView{
protected:
std::string _name;
public:
virtual ~IUIView() {};
public:
virtual void insert(IUIView* view) = 0;
virtual void remove(IUIView* view) = 0;
virtual void drawRect(float x,float y,float width,float height) = 0;
};
//叶子视图,不具备添加子视图的能力
class LeafView:public IUIView{
public:
virtual ~LeafView(){}
LeafView(std::string name){
_name = name;
}
void insert(IUIView* view){
}
void remove(IUIView* view){
}
void drawRect(float x,float y,float width,float height){
std::cout <<" LeafView drawRect name:"<< _name <<std::endl;
}
};
//合成部件视图,具备添加子视图的能力
class ComponentView:public IUIView{
private:
std::set<IUIView*> _set;
public:
virtual ~ComponentView(){}
ComponentView(std::string name){
_name = name;
}
void insert(IUIView* view){
if (!view) {
return;
}
_set.insert(view);
}
void remove(IUIView* view){
if (!view) {
return;
}
_set.erase(view);
}
void drawRect(float x,float y,float width,float height){
for (std::set<IUIView*>::iterator iter = _set.begin(); iter != _set.end();++iter) {
((IUIView*)(*iter)) -> drawRect(x, y, width, height);
}
std::cout <<" ComponentView drawRect name:" << _name <<std::endl;
}
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
IUIView* rootView = new ComponentView("rootView");
IUIView* componentView1 = new ComponentView("componentView1");
IUIView* componentView2 = new ComponentView("componentView2");
IUIView* leafView1_1 = new LeafView("leafView1_1");
IUIView* leafView1_2 = new LeafView("leafView1_2");
IUIView* leafView2_1 = new LeafView("leafView2_1");
IUIView* leafView2_2 = new LeafView("leafView2_2");
rootView -> insert(componentView1);
rootView -> insert(componentView2);
componentView1 -> insert(leafView1_1);
componentView1 -> insert(leafView1_2);
componentView2 -> insert(leafView2_1);
componentView2 -> insert(leafView2_2);
componentView2 -> remove(leafView2_2);
rootView -> drawRect(0, 0, 0, 0);
}
return 0;
}
输出: