设计模式-装饰器模式

定义:
不改变原有对象的前提下,动态地给一个对象增加一些额外的功能.

成员:

  • Component, 抽象组件
  • ConcreteComponent, 具体组件
  • Decorator, 抽象装饰器
  • ConcreteDecorator, 具体装饰器

类图:

实例:
装饰器复合开闭原则,在不改变原有类的结构下增加类的功能.例如,HeadFirst系列里的经典案例星巴兹咖啡,定义一个Coffee的抽象类,只能提供咖啡,但通过装饰器SugarCoffee装饰之后扩展了新功能,另外你还可以加点奶之类.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 咖啡抽象类
@interface Coffee : NSObject

- (CGFloat)getCoffeePrice;

@end

@implementation Coffee

- (CGFloat)getCoffeePrice
{
return 0.f;
}

@end

// 调料装饰器抽象类
@interface CondimentDecorator : Coffee

@propety (nonatomic, strong) Coffee *coffee;
- (instancetpe)initWithCoffee:(Coffee *)coffee;

@end

@implementation CondimentDecorator

- (instancetype)initWithCoffee:(Coffee *)coffee
{
self = [super init];
if (self)
{
self.coffee = coffee;
}
return self;
}

@end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 具体的Coffee
@interface ACoffee : Coffee

- (CGFloat)getCoffeePrice;

@end

@implementation : ACoffee

- (CGFloat)getCoffeePrice
{
return 1.99;
}

- (NSString *)description
{
return @"A Coffee";
}

@end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 具体的装饰器
@inteface SugerDecorator : CondimentDecorator

@end

@implementation SugerDecorator

- (CGFloat)getCoffeePrice
{
return [self.coffee getCoffeePrice] + 0.3;
}

- (NSString *)description
{
return [NSString stringWithFormat:@"%@-Sugar",[self.coffee description]];
}

@end

1
2
3
4
// 使用
Coffee *coffee = [ACoffee new];
coffee = [[SugerDecorator alloc] initWithCoffee:coffee];
NSLog(@"%@-----%@",coffee,@([coffee getCoffeePrice]));

优点:

  • 装饰器避免了修改原有功能代码,复合开闭原则
  • 装饰器在运行时可以动态为对象添加功能,从而达到不同的效果

缺点:

  • 需要根据每一个扩展的功能添加具体的装饰类,增加类的数量

总结:

  • 对一些类业务本身比较复杂,继承关系比较多的时候,可以考虑用装饰器来扩展