装饰器模式
2019-08-04 本文已影响0人
FY_Chao
What 装饰者模式
在面向对象编程中,滥用继承是一个很常见的问题,尤其是新手程序员,继承虽然能一定程度的解决问题,但是滥用会导致很难维护、扩展的现有的代码。
装饰器模式: 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
标准的装饰模式包括一个抽象父类Component
,它为其他具体组件(conreteComponent)声明了一些操作,抽象的Component
可以细化为另一个Decorator
的抽象类。Decorator
的抽象类会持有一个Component
实例,而conreteDecorator
会在Decorator
抽象类的基础上扩展一些自己的行为。
例子1
下面以星巴克的咖啡举栗子,假设所有的咖啡有个抽象的父类 Beverage(饮料)
,所有的咖啡(拿铁、黑咖、意式浓缩等)都会继承于 Beverage(饮料)
,同时存在抽象装饰器CondimentDecorator
也是继承抽象父类Beverage(饮料)
,其它的具体装饰器类Soy(豆浆)
、Mocha (摩卡)
等继承抽象装饰器CondimentDecorator
。客人点单的时候有时候需要摩卡咖啡、摩卡豆浆拿铁等。我们可以用具体装饰器类来修饰Component
。
具体代码:
// Components
// Abstract Super Class
public class Beverage {
var description = "Unknow Beverage"
func getDescription() -> String {
return description
}
func cost() -> Double {
return 0
}
}
public class Espresso: Beverage {
override init() {
super.init()
description = "Espresso"
}
override func cost() -> Double {
return 1.99
}
}
public class BlackCoffe: Beverage {
override init() {
super.init()
description = "BlackCoffe"
}
override func cost() -> Double {
return 0.99
}
}
# Decorators
// Abstract Class
class condimentDecorator: Beverage {
override func getDescription() -> String {
return "Abstract condimentDecorator"
}
}
class Mocha: condimentDecorator {
var beverage: Beverage
init(beverage: Beverage) {
self.beverage = beverage
super.init()
}
override func getDescription() -> String {
return beverage.getDescription() + ",Mocha"
}
override func cost() -> Double {
return beverage.cost() + 0.2
}
}
class Soy: condimentDecorator {
var beverage: Beverage
init(beverage: Beverage) {
self.beverage = beverage
super.init()
}
override func getDescription() -> String {
return beverage.getDescription() + ",Soy"
}
override func cost() -> Double {
return beverage.cost() + 0.5
}
}
再具体调用的时候:
var beverage = Espresso() as Beverage
print(beverage.getDescription(),beverage.cost())
beverage = Mocha(beverage: beverage) as Beverage
print(beverage.getDescription(),beverage.cost())
beverage = Soy(beverage: beverage) as Beverage
print(beverage.getDescription(),beverage.cost())
设计原则
- 类应该对扩展开放,对修改关闭