什么是装饰器模式?
动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案.
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
模式包含角色 :
抽象构件类(Component):给出一个抽象的接口,用以规范准备接收附加责任的对象
具体构件类(ConcreteComponent):定义一个具体的准备接受附加责任的类,其必须实现Component接口。
装饰者类(Decorator):持有一个构件(Conponent)对象的实例,并定义一个和抽象构件一致的接口。
具体装饰者类(ConcreteDecoratator):定义给构件对象“贴上”附加责任。
优缺点:
1、装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
2、通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
3、装饰器完全遵守开闭原则。
缺点:
1、会出现更多的代码,更多的类,增加程序复杂性。
2、动态装饰时,多层装饰时会更复杂。追踪代码更难看点
如何使用?
我们来为一个gamePad设计一个装饰器:
一个GamePad包含了很多操作,我们声明一个类,并实现相应的方法比如up down left等
@interface GamePad : NSObject
/**
* 上下左右的操作
*/
- (void)up;
- (void)down;
- (void)left;
- (void)right;
/**
* 选择与开始的操作
*/
- (void)select;
- (void)start;
/**
* 按钮 A + B + X + Y
*/
- (void)commandA;
- (void)commandB;
- (void)commandX;
- (void)commandY;
@end
在不改变这个类结构的情况下,给他添加新的功能。
设计一个GamePadDecorator类,其中包含了GamePad对象,所有的操作,都通过GamePadDecorator中转到GamePad对象来进行调用。
#import "GamePadDecorator.h"
#import "GamePad.h"
@interface GamePadDecorator ()
@property (nonatomic, strong) GamePad *gamePad;
@end
@implementation GamePadDecorator
- (instancetype)init {
self = [super init];
if (self) {
self.gamePad = [[GamePad alloc] init];
}
return self;
}
- (void)up {
[self.gamePad up];
}
- (void)down {
[self.gamePad down];
}
- (void)left {
[self.gamePad left];
}
- (void)right {
[self.gamePad right];
}
- (void)select {
[self.gamePad select];
}
- (void)start {
[self.gamePad start];
}
- (void)commandA {
[self.gamePad commandA];
}
- (void)commandB {
[self.gamePad commandB];
}
- (void)commandX {
[self.gamePad commandX];
}
- (void)commandY {
[self.gamePad commandY];
}
@end
如果要添加一个新的功能。我们在设计个CheatGamePadDecorator装饰器类来继承GamePadDecorator类。
#import "CheatGamePadDecorator.h"
@implementation CheatGamePadDecorator
- (void)cheat {
[self up];
[self down];
[self up];
[self down];
[self left];
[self right];
[self left];
[self right];
[self commandA];
[self commandB];
[self commandA];
[self commandB];
}
@end
如何使用呢?
GamePadDecorator *gamePadDecorator = [[GamePadDecorator alloc] init];
[gamePadDecorator up];
CheatGamePadDecorator *cheatPamePad = [[CheatGamePadDecorator alloc] init];
[cheatPamePad cheat];
我们分别通过这两个装饰器来进行调用,把GamePad与业务隔绝开。
网友评论