装饰者模式的定义:动态地将对象附加到对象上。想要扩展功能。装饰者能提供有别于继承的另一种选择.
现有以下场景:
星巴兹咖啡厅需要做一套点餐系统,他们现在有Espresso,HouseBlend,DarkRoast,Decaf等咖啡,顾客还可以添加milk、mocha、soy及whip等调料。每种咖啡及调料的价格都不相同,该系统要反应出顾客所点咖啡、调料及价钱。其中,Espresso等咖啡是被装饰者(decorated),milk等调料是装饰者(decorator).
首先,我们创建一个WYXBeverage的基类
#import <Foundation/Foundation.h>
@interface WYXBeverage : NSObject
// 返回 beverage 描述
- (NSString *)descriptionBeverage;
// 返回价钱
- (double)cost;
@end
但都不做具体实现
#import "WYXBeverage.h"
@implementation WYXBeverage
- (NSString *)descriptionBeverage{
return @"";
}
- (double)cost{
return 0;
}
@end```
创建被装饰者 HouseBlend,该类继承自WYXBeverage,并重写父类的两个方法
import "WYXHouseBlend.h"
@implementation WYXHouseBlend
-
(NSString *)descriptionBeverage{
return @"HouseBlend";
} -
(double)cost{
return 30;
}
@end```
再创建 一个所有装饰者的基类:WYXDecorator,该基类必需继承自WYXBeverage。不需要重写父类的两个方法,但要增加一个构造方法:
//
// WYXDecorator.h
// DecoratorPattern
// 所有装饰者的基类,也必须继承自 WYXBeverage
// Created by 颖 on 2016/12/20.
// Copyright © 2016年 ying. All rights reserved.
//
#import "WYXBeverage.h"
@interface WYXDecorator : WYXBeverage
// 用来存放被装饰者 或者 上一个装饰者
@property (nonatomic, strong) WYXBeverage *beverage;
// 构造方法中需要接收 被装饰者 或者 上一个装饰者
- (instancetype)initWithBeverage:(WYXBeverage *)beverage;
@end
其构造方法的实现
@implementation WYXDecorator
- (instancetype)initWithBeverage:(WYXBeverage *)beverage{
self = [super init];
if (self) {
// 接收 被装饰者 或者 上一个装饰者
self.beverage = beverage;
}
return self;
}
@end```
再创建milk具体装饰者:WYXMilk,该类必须继承自WYXDecorator,并重写父类WYXBeverage的方法:
@implementation WYXDecorator
- (instancetype)initWithBeverage:(WYXBeverage *)beverage{
self = [super init];
if (self) {
// 接收 被装饰者 或者 上一个装饰者
self.beverage = beverage;
}
return self;
}
@end```
同理,再创建soy类与whip类两个装饰者。
现在让我们来点一杯加了milk、soy怀whip的houseBlend
// 一杯混合咖啡
WYXBeverage *houseblend = [[WYXHouseBlend alloc] init];
// 加奶
houseblend = [[WYXMilk alloc] initWithBeverage:houseblend];
// 加豆浆
houseblend = [[WYXSoy alloc] initWithBeverage:houseblend];
// 加奶泡
houseblend = [[WYXWhip alloc] initWithBeverage:houseblend];
NSLog(@"%@",houseblend.descriptionBeverage);
NSLog(@"%f",houseblend.cost);```
打印结果:
2016-12-21 21:46:09.787 DecoratorPattern[2047:190947] HouseBlen + milk + soy + whip
2016-12-21 21:46:09.787 DecoratorPattern[2047:190947] 41.500000```
*思考点:基类的返回值类型改变,那么就要在各个子类做好多复制粘贴工作! *
网友评论