装饰者模式:
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
该模式的组成部分:
- 一个共同的抽象类(父类,也可以是接口)
- 具体的被装饰者类(可以是多个)
- 一个抽象的装饰者类 和 多个具体的装饰者类
注:
- 不需要 额外的被装饰者的抽象类 是因为 共同的抽象类 即是 被装饰者 的父类。也就是说其实在装饰者模式中,装饰者和被装饰者都共同源于一个父类。
- 需要一个 额外的装饰者的抽象类 是因为 装饰类 可以额外的定义一些方法 来完成对被装饰类 的装饰。
UML 类图如下:
代码的具体实现:
1、公共抽象类:
// 定义一个饮料类充当 装饰者与被装饰者的共同 抽象父类 class Beverage: NSObject { var beverageDescription: String = "" // 返回 描述信息 func getBeverageDescription() -> String { return self.beverageDescription } // 需要被 装饰 的方法 func cost() -> Float { return 0; } }
2、被装饰者部分:
// 一个具体的被装饰者类:HouseBlend class HouseBlend: Beverage { override init() { super.init() self.beverageDescription = "It's HouseBlend" } // 需要被 装饰 的方法 override func cost() -> Float { return 0.9 } }
3、装饰者部分:
// 装饰者的抽象类(但是在这里,我定义了一个 有实现了接口的类 充当 装饰者的抽象类) class CondimentDecortor: Beverage { // 装饰者类 需要一个 被装饰者 的对象 var concreteDrink: Beverage! // 因为这个方法 在装饰者类中是通用的, 所以我在父类中实现了,以节约代码量 override func getBeverageDescription() -> String { return "\(self.concreteDrink.getBeverageDescription()) With \(self.beverageDescription)" } } // 一个具体的装饰者类: Milk class Milk: CondimentDecortor { // 在初始化的时候 将自己的被装饰类 具体化(赋以对象) init(cDrink: Beverage) { super.init() self.concreteDrink = cDrink self.beverageDescription = "Milk" } // 装饰(扩充) Cost 方法 override func cost() -> Float { return concreteDrink!.cost() + 0.1; } }
4、测试代码:
println("********* WelCome To StarBucks Coffee *********") // 一杯不需要任何调料的 Coffee var drink: Beverage = HouseBlend() println("\(drink.getBeverageDescription()) \nAnd $ is \(drink.cost())") // 一杯需要加 牛奶 和 大豆 的 Coffee var drink1: Beverage = HouseBlend() drink1 = Milk(cDrink: drink1) drink1 = Soy(cDrink: drink1) println("\(drink1.getBeverageDescription()) \nAnd $ is \(drink1.cost())")
5、 测试结果: