天天看點

swift設計模式:(三)裝飾者模式(Decorator Pattern)裝飾者模式一、通過示例認識裝飾者模式

裝飾者模式

定義:動态的将責任附加到對象上,若要擴充功能,裝飾者提供了比繼承更有彈性的替代方案。

另一種表達方式:對原有的物體進行裝飾,給原有的物體添加上新的裝飾品。

裝飾者模式很好的展現了 開放關閉原則,即類應該對擴充開放 對修改關閉。

舉例說明:

有一個禮物,我們想要對其進行包裝,禮物是被裝飾者 即 元件Component,包裝盒以及包裝盒上的花等等就是裝飾品 即 裝飾者Decorator。

換成花瓶與鮮花,花瓶是Component,鮮花是Decorator。

一、通過示例認識裝飾者模式

場景:花瓶和鮮花的關系

根據設計原則“封裝變化” 即 要将變化的東西進行封裝提取。裝飾者模式中 所使用的裝飾就是變化的部分 即 對應着示例中的 鮮花,因為往花瓶中插花的過程就是鮮花變化的過程 即 為花瓶裝飾的過程,花瓶就是元件。

注意:

裝飾者 = 舊元件 + 新裝飾品

下方是元件與裝飾者之前的關系“類圖”

swift設計模式:(三)裝飾者模式(Decorator Pattern)裝飾者模式一、通過示例認識裝飾者模式

而我們要實作的 花瓶和鮮花 示例“類圖”如下所示

swift設計模式:(三)裝飾者模式(Decorator Pattern)裝飾者模式一、通過示例認識裝飾者模式

圖中上方紅框部分就是所有鮮花 即 裝飾者Decorator

下方紅框部分就是花瓶 即 元件Component

1、所有類的基類VaseComponent 即 花瓶元件

參數 說明
description 用來描述xxx花瓶裝有xxx花
函數 說明
display() 用來列印description描述資訊的

2、所有鮮花的基類FlowerDecorator

繼承自VaseComponent,因為裝飾者擁有被裝飾者對象的同時又需要添加新的裝飾物,是以無論是裝飾者還是被裝飾者都有共同的基類

參數 說明
vase VaseComponent的對象,可以是沒有任何裝飾的花瓶,也可以是已經添加了裝飾的花瓶

3、如何實作裝飾者模式?

利用 多态

4、具體實作

1)實作空花瓶的基類–VaseComponent

參數 說明
description 存儲的是花瓶的描述資訊,例如:瓷花瓶、玻璃花瓶
函數 說明
getDescription() 用來擷取description存儲的描述資訊的
display() 對getDescription()擷取的值進行列印
//花瓶的基類
class VaseComponent{
    //對花瓶進行描述
    private var description : String
    
    init(_ description : String = "花瓶") {
        self.description = description
    }
    
    //擷取description存儲的描述資訊
    func getDescription()->String{
        return self.description
    }
    
    func display(){
        //列印描述資訊
        print(getDescription())
    }
}
           

2)建立空花瓶

建立一個瓷花瓶Porcelain、一個玻璃花瓶Glass,等着其他鮮花來裝飾

函數 說明
init() 調用父類初始化時為父類中的description字段進行初始化
//建立特定的花瓶
class Porcelain : VaseComponent{
    init() {
        super.init("瓷花瓶:")
    }
}
class Glass : VaseComponent{
    init() {
        super.init("玻璃花瓶:")
    }
}
           

3)實作鮮花的基類—FlowerDecorator

參數 說明
vase 用于存儲舊元件 即 上一次被裝飾過的花瓶元件
函數 說明
init(vase) 裝飾者在初始化時會指定上次被修改後的元件
//鮮花的父類,因為裝飾者就是最新的花瓶元件,是以要繼承自VaseComponent
class FlowerDecorator : VaseComponent{
    //用于存儲 “舊元件” 即上次被裝飾過的花瓶元件
    var vase : VaseComponent
    
    //“裝飾者”在初始化時會指定上次被修飾後的元件(空花瓶或者其他修飾者的對象)
    init(_ vase : VaseComponent) {
        self.vase = vase
    }
}
           

4)實作各個裝飾者

函數 說明
getDescription() 重寫了基類的該方法,為上一個裝飾者添加新的裝飾品
//往花瓶裡加入特定的花進行裝飾
//玫瑰花
class Rose : FlowerDecorator{
    
    override init(_ vase: VaseComponent) {
        super.init(vase)
    }
    
    override func getDescription() -> String {
        return vase.getDescription() + "玫瑰 "
    }
}
//百合花
class Lily : FlowerDecorator{
    override init(_ vase: VaseComponent) {
        super.init(vase)
    }
    
    override func getDescription() -> String {
        return vase.getDescription() + "百合 "
    }
}
           

4、測試

//建立空花瓶
    var porcelain : VaseComponent = Porcelain()
    //列印最新的描述資訊
    porcelain.display()
    //插入玫瑰
    porcelain = Rose(porcelain)
    //插入百合
    porcelain = Lily(porcelain)
    //列印最新的描述資訊
    porcelain.display()
           

測試結果

swift設計模式:(三)裝飾者模式(Decorator Pattern)裝飾者模式一、通過示例認識裝飾者模式

上述測試用例的具體調用方式如下:

swift設計模式:(三)裝飾者模式(Decorator Pattern)裝飾者模式一、通過示例認識裝飾者模式

1)我們為procelain對象添加了兩個裝飾品,最終的procelain對象是Lily對象,是 空瓷瓶+玫瑰+百合 的組合體

2)調用display()方法時,會調用該對象的 getDescription()方法,而該對象中的getDescription()方法會調用上一個裝飾者 即 Rose 對象的getDescription()方法,最終會找到 元件 即 空瓷瓶中的 getDescription()方法

繼續閱讀