理解:给已有的类增加功能,动态的
阿呆觉得自己好弱,于是买了个手套式机关枪和机械翅膀装备在身上,让自己更强。战斗结束后,把装备卸下,阿呆仍旧是阿呆,没变。
简单关系图:
代码示例:
// 世间万物嘛,所有东西都属于它。抽象类,直接用协议来写了
@protocol TianXiaWanWU <NSObject>
- (void)show;
@end
// 阿呆 ADai.h
#import "TianXiaWanWU.h"
@interface ADai : NSObject <TianXiaWanWU> 遵守协议,相当于继承抽象类
@end
// ADai.m
@implementation ADai
- (void)show
{
NSLog(@"装备完成");
}
@end
// 装备父类 ZhuangBei.h
#import "TianXiaWanWU.h"
@interface ZhuangBei : NSObject <TianXiaWanWU>
@property (nonatomic,assign) id<TianXiaWanWU> people;
@end
// ZhuangBei.m
@implementation ZhuangBei
- (void)setPeople:(id<TianXiaWanWU>)people
{
_people = people;
}
- (void)show
{
[_people show];
}
@end
// 机关枪 JiGuanQiang.h
@interface JiGuanQiang : ZhuangBei
- (void)show;
@end
//JiGuanQiang.m
@implementation JiGuanQiang
- (void)show
{
NSLog(@"装备机关枪");
[super show];
}
@end
// CiBang.h
@interface CiBang : ZhuangBei
- (void)show;
@end
// CiBang.m
@implementation CiBang
- (void)show
{
NSLog(@"装备翅膀");
[super show];
}
@end
// 客户端调用
- (void)viewDidLoad
{
[super viewDidLoad];
ADai *aDai = [[ADai alloc] init]; // 一个阿呆
JiGuanQiang *jgq = [[JiGuanQiang alloc] init]; // 机关枪
CiBang *cb = [[CiBang alloc] init]; // 翅膀
jgq.people = aDai; // 阿呆穿上机关枪
cb.people = jgq;// 穿上机关枪的阿呆,再穿上翅膀
[cb show];
}
大概流程:
(1)这个是有个顺序的。
1.[cb show]首先执行了自己的NSLog然后去执行[super show],而父类的show方法实现是[_people show],也就是people属性是谁,就去执行谁的show
2.因为cb的people是jgq,使用又去执行了jgq的show。也是先执行了自己的NSLog然后去执行[super show]。
3.jgq的people是aDai于是就执行aDai的show。
感觉ZhuangBei(所有装饰者的父类)这个类就像个路由,总是调整过来的人到该去的地方去。
(2)还有另一种情况
上面那种是吧[super show]放在下面,即先执行自己的功能才执行,最后才执行被装饰类的功能。如果想要先执行被装饰类的功能,那么把[super show]放在,本类功能前面即可。
大概的流程:
1.[cb show]先执行了[super show],因为cb的people是jqg,所以跳到jqg中执行show。
2.jgq也是先执行[super show],因为jqg的people是aDai 所以执行了他的show
3.回到jgq执行自己的功能,再回到cb执行自己的功能
怎么说呢,看起来有点像递归的感觉
优点:
1.动态的增加类的功能,而不使过于庞大。
2.主要逻辑与装饰功能分开。// 阿呆就一个普通人,不能总是让他整天穿着装备生活,多累啊
适用性:
1.在不能或不想生成子类的情况下,动态添加功能时
2.想动态增加或撤销功能