其实组合模式就是为了便于管理一个树形结构(抽象的)的对象,能让客户端统一处理这个对象的一种设计模式
举个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 帽子 |_贝雷帽 |_鸭舌帽 |_黑色鸭舌 衣服 |_衬衫 |_蓝色衬衫 |_白色衬衫 |_T恤 裤子 |_牛仔裤 |_蓝色牛仔裤 |_短裤
|
那么这时候如果客户端要拿到一顶黑色鸭舌帽,一件白色衬衫和一条蓝色牛仔裤,那么应该怎么取到呢?或者想从对象中删除这些东西呢?
首先我们需要有一个衣柜
1
| Wardrobe *wardrobe = [[Wardrobe alloc] init];
|
然后为其我们添加子节点
1 2 3
| [wardrobe addDress:hat]; [wardrobe addDress:clothes]; [wardrobe addDress:trousers];
|
那 hat
和 clothes
和 trousers
怎么来 (以 hat 举例)
1 2 3 4 5 6 7 8 9
| Hat *hat = [[Hat alloc] init]; Hat *yashe_hat = [[Hat alloc] initWithType:@"Yashe"]; Hat *beilei_hat = [[Hat alloc] initWithType:@"Beilei"]; Hat *black_hat = [[Hat alloc] initWithColor:@"Black Yashe"];
[hat addDress:beilei_hat];
[yashe_hat addDress:black_hat]; [hat addDress:yashe_hat];
|
现在我们需要注意一下
· 上面的三个对象,必须遵守一个协议,我们姑且命名为 DressProtocol (服饰)
1 2 3 4 5 6 7 8
| @protocol DressProtocol
- (void)addDress:(id<DressProtocol>)dress; - (void)removeDress:(id<DressProtocol>)dress;
- (void)showDresses; @end
|
上面经过一轮 AddDress:之后,帽子那块应该就会生成这样子的结构
1 2 3 4 5
| 衣橱 |_帽子 |_贝雷帽 |_鸭舌帽 |_黑色鸭舌帽
|
然后我们来看看里面代理方法的实现
1 2 3 4 5 6 7 8 9 10 11 12 13
| - (void)addDress:(id<DressProtocol>)dress { // 有一个数组成员属性用来储存这些对象 [_child addObject:dress]; } - (void)removeDress:(id<DressProtocol>)dress { [_child removeObject:dress]; } - (void)showDresses { NSLog(@"%@",_child); }
|
顺便看看 Init的时候我们使用的两个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| - (instancetype)initWithType:(NSString *)type { if(self = [super init]){ self.type = type; self.color = nil; } return self; }
- (instancetype)initWithColor:(NSString *)color { if(self = [super init]){ self.type = nil; self.color = color; } return self; }
|
大概就是这种感觉
如果不是很清楚的话,可以想想 UIView
的 addSubView:
addSubView:
就是把一个新的 View加入到子节点,如果 subView 还有 subView,那就在 subView 上面继续添加 addSubView:
最后我们打印 subViews的时候就可以得到该View的所有的subview