概念
装饰器模式是一种结构型设计模式,它允许你在不修改原有类的情况下,通过"包裹"的方式动态地为对象添加新功能。与继承不同,它在运行时灵活组合,符合开闭原则(对扩展开放,对修改关闭)。
适用场景
适用于 在基本功能基础上,进行功能叠加场景。
角色
协议:行为抽象
功能组件:遵守协议,实现基础功能
装饰器基类:遵守协议,持有功能组件,调用转发
装饰器扩展:继承自装饰器基类,通过重载,进行行为扩展(功能叠加)
示例:咖啡配料系统
- 定义协议
protocol Coffee {
func description() -> String
func cost() -> Double
}
- 功能组件,遵守协议。
实现基本功能。
class PlainCoffee: Coffee {
func description() -> String { "简单咖啡" }
func cost() -> Double { 10.0 }
}
- 基础装饰器(持有引用功能组件,同时也遵守协议,转发调用)
作为基类
class CoffeeDecorator: Coffee {
private let decoratedCoffee: Coffee
init(_ coffee: Coffee) {
self.decoratedCoffee = coffee
}
// 协议调用 转发
func description() -> String {
decoratedCoffee.description()
}
func cost() -> Double {
decoratedCoffee.cost()
}
}
- 具体装饰器(扩展行为)
继承自 基础装饰器,重载;
职责单一: 每个装饰器只做一件事,(每种功能分开写在一个子类中
class MilkDecorator: CoffeeDecorator {
override func description() -> String {
super.description() + ",加牛奶"
}
override func cost() -> Double {
super.cost() + 5.0
}
}
class SugarDecorator: CoffeeDecorator {
override func description() -> String {
super.description() + ",加糖"
}
override func cost() -> Double {
super.cost() + 3.0
}
}
class VanillaDecorator: CoffeeDecorator {
override func description() -> String {
super.description() + ",香草风味"
}
override func cost() -> Double {
super.cost() + 8.0
}
}
- 灵活组合
功能一层一层加
let plain = PlainCoffee()
print(plain.description()) // 简单咖啡
print(plain.cost()) // 10.0
// 组合 叠加
let milkCoffee = MilkDecorator(plain)
let sugerCoffee = SugarDecorator(milkCoffee)
let fancyCoffee = VanillaDecorator(sugerCoffee)
print(fancyCoffee.description())
// 简单咖啡,加牛奶,加糖,香草风味
print(fancyCoffee.cost())
// 26.0(10 + 5 + 3 + 8)
- 可扩展性:
需要加其他功能?只需再写一个对应的装饰器,插入链中,其他代码零修改。