天天看点

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()方法

继续阅读