iOS --设计模式(3、装饰者模式)

装饰者模式的定义:动态地将对象附加到对象上。想要扩展功能。装饰者能提供有别于继承的另一种选择.

现有以下场景:
星巴兹咖啡厅需要做一套点餐系统,他们现在有Espresso,HouseBlend,DarkRoast,Decaf等咖啡,顾客还可以添加milk、mocha、soy及whip等调料。每种咖啡及调料的价格都不相同,该系统要反应出顾客所点咖啡、调料及价钱。其中,Espresso等咖啡是被装饰者(decorated),milk等调料是装饰者(decorator).

首先,我们创建一个WYXBeverage的基类

#import 

@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```

原码地址

*思考点:基类的返回值类型改变,那么就要在各个子类做好多复制粘贴工作! *

你可能感兴趣的:(iOS --设计模式(3、装饰者模式))