《大話設(shè)計模式》第 6 章 - 裝飾模式 的 Swift 實現(xiàn)。
問題
對一個人進行裝扮,衣服、鞋子、領(lǐng)帶等等,考慮不同的人有不同裝扮,并且便于增加裝扮。
方案
把裝飾功能按特性的不同拆分到各自單獨的子類中,交給交互端根據(jù)需要進行組合搭配,每個裝飾類傳入上一個裝飾完成之后的對象,這樣就能把用戶選擇的裝飾串聯(lián)起來,完成最終的裝飾,同時裝飾類隨時可以添加,不影響已有的裝飾。
1. Component,定義一個接口協(xié)議,抽象化裝飾組件
protocol Person{
func show()
}
2. ConcreteComponent 類,定義具體的對象,也可以給這個對象添加一些職責(zé)
class SimplePerson: Person{
private let name: String
init(name: String){
self.name = name
}
func show(){
print("裝扮的 \(name) ")
}
}
3. Decorator,裝飾類,遵循 Component 協(xié)議。Component 無需知道 Decorator 的存在。
required 關(guān)鍵字要求子類必須傳入裝飾過的對象。并在裝飾方法中執(zhí)行實例對象的核心方法。
class PersonDecorator: Person{
let decoratedPerson: Person
required init(decorated: Person){
self.decoratedPerson = decorated
}
func show() {
decoratedPerson.show()
}
}
4. ConcreteDecorator,具體的裝飾器,實現(xiàn) component 要的職責(zé)。
Decorator 的子類,初始化方法中傳入一個已裝飾的對象,依次應(yīng)用裝飾類,就可以把用到的裝飾組合起來。
final class Tee: PersonDecorator{
required init(decorated: Person) {
super.init(decorated: decorated)
}
override func show() {
print("T恤", separator: "", terminator: " ")
super.show()
}
}
final class BeachShorts: PersonDecorator{
required init(decorated: Person) {
super.init(decorated: decorated)
}
override func show() {
print("沙灘褲", separator: "", terminator: " ")
super.show()
}
}
final class Sunglasses: PersonDecorator{
required init(decorated: Person) {
super.init(decorated: decorated)
}
override func show() {
print("墨鏡", separator: "", terminator: " ")
super.show()
}
}
測試
var someone: Person = SimplePerson(name: "Tom") //即將被裝飾的對象,可以有一些基礎(chǔ)屬性
someone = Tee(decorated: someone) //用 Tee 去裝飾 someone
someone = BeachShorts(decorated: someone) //在上一步裝飾好之后繼續(xù)裝飾
someone = Sunglasses(decorated: someone) //繼續(xù)用 Sunglasses 去裝飾前兩步裝飾過的對象
someone.show()
輸出
墨鏡 沙灘褲 T恤 裝扮的 Tom
總結(jié)
裝飾模式是為已有功能動態(tài)添加更多功能的一種方式。把每個裝飾功能放在單獨的類中,并用這個類包裝它所要裝飾的對象??蛻舸a可以根據(jù)需要有選擇地使用裝飾功能來依次包裝對象,可以以隨意的順序組合裝飾。
這樣有效地把類的核心功能和裝飾功能區(qū)分開。要增加裝飾時不需要改動任何已有代碼。