装饰者模式

来源:互联网 发布:mysql查询最小时间 编辑:程序博客网 时间:2024/06/06 03:01

理解:给已有的类增加功能,动态的


阿呆觉得自己好弱,于是买了个手套式机关枪和机械翅膀装备在身上,让自己更强。战斗结束后,把装备卸下,阿呆仍旧是阿呆,没变。


简单关系图:



代码示例:

// 世间万物嘛,所有东西都属于它。抽象类,直接用协议来写了@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.想动态增加或撤销功能

0 0
原创粉丝点击