装饰模式

这节课的讲解是以一个人的装扮作为例子的,下面来看看第一版的代码.

第一版(没有遵守开放-封闭原则)

人物类

class Person: NSObject {
    private var name:String?
    
    init(name:String) {
        self.name = name
    }
    
    func wearTShirts(){
        print("大T恤")
    }
    
    func wearBigTrouser(){
        print("垮裤")
    }
    
    func wearSneakers(){
        print("球鞋")
    }
    
    func wearSuit(){
        print("西装")
    }
    
    func wearTie(){
        print("领带")
    }
    
    func wearLeatherShoes(){
        print("皮鞋")
    }
    
    func show(){
        print("装扮的",name!)
    }
}

客户端代码

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let wz = Person(name: "旺仔")
        print("第一种装扮:")
        wz.wearTShirts()
        wz.wearBigTrouser()
        wz.wearSneakers()
        wz.show()
        /*
         第一种装扮:
         大T恤
         垮裤
         球鞋
         装扮的 旺仔
         */
        print("第二种装扮:")
        wz.wearSuit()
        wz.wearTie()
        wz.wearLeatherShoes()
        wz.show()
        /*
         第二种装扮:
         西装
         领带
         皮鞋
         装扮的 旺仔
         */
    }
}

在第一版中,如果我们需要增加其他人的装扮,那就只能去修改Person类的代码,这样违反了开放封闭的原则(虽然我现在一直违反着,但既然是在学习我们就要牢记这一观点,改代码去)

第二版

Person类

class Person: NSObject {
    private var name:String?
    
    init(name:String) {
        self.name = name
    }
    
    func show(){
        print("装扮的",name!)
    }
}

服装抽象类

class Finery: NSObject {
    func show(){
    }
}

服装具体类

class TShirts: Finery {
    override func show() {
        print("大T恤")
    }
}

class BigTrouser: Finery {
    override func show() {
        print("垮裤")
    }
}

class Sneakers: Finery {
    override func show() {
        print("球鞋")
    }
}

class Suit: Finery {
    override func show() {
        print("西装")
    }
}

class Tie: Finery {
    override func show() {
        print("领带")
    }
}

class LeatherShoes: Finery {
    override func show() {
        print("皮鞋")
    }
}

客户端类

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let wz = Person(name: "旺仔")
        print("第一种装扮:")
        let dtx = TShirts()
        let kk = BigTrouser()
        let pqx = Sneakers()
        dtx.show()
        kk.show()
        pqx.show()
        wz.show()
        /*
         第一种装扮:
         大T恤
         垮裤
         球鞋
         装扮的 旺仔
         */
        print("第二种装扮:")
        let xz = Suit()
        let ld = Tie()
        let px = LeatherShoes()
        xz.show()
        ld.show()
        px.show()
        wz.show()
        /*
         第二种装扮:
         西装
         领带
         皮鞋
         装扮的 旺仔
         */
    }
}

但是这样的话相当于把所有的对象都暴露出来了,这肯定不是我们所希望的

装饰模式

动态地给一个对象添加一些额外的职责,就增加功能来说, 装饰模式比生成子类更为灵活
来看看代码

class Component: NSObject {
    func operation(){
        
    }
}

class ConcreteComponent: Component {
    override func operation() {
        print("具体对象的操作")
    }
}

class Decorator: Component {
    var component: Component?
    
    // 设置component
    func setterComponent(component:Component){
        self.component = component
    }
    override func operation() {
        // 重写父类方法
        if component != nil {
            // 执行Component的operation方法
            component?.operation()
        }
    }
}

class ConcreteComponentA: Decorator {
    private var addedState:String = ""

    override func operation() {
        super.operation()
        addedState = "New State"
        print("具体装饰对象A的操作")
    }
}

class ConcreteComponentB: Decorator {
    
    override func operation() {
        super.operation()
        addedBehavior()
        print("具体装饰对象B的操作")
    }
    
    func addedBehavior(){
        
    }
}

客户端代码

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        var c = ConcreteComponent()
        var d1 = ConcreteComponentA()
        var d2 = ConcreteComponentB()
        d1.setterComponent(c)
        d2.setterComponent(d1)
        d2.operation()
        /*
         具体对象的操作
         具体装饰对象A的操作
         具体装饰对象B的操作
         */
    }
}

来看看第三版代码怎么套入装饰模式中

class Person: NSObject {
    // 等同于装饰模式中的 ConcreteComponent类
    private var name:String?
    
    init(name:String) {
        self.name = name
    }
    
    override init() {
        //这里需要一个空的初始化方法
    }
    
    func show(){
        print("装扮的",name!)
    }
}
class Finery: Person {
    //(Decorator类)
    var component:Person?
    
    func decorate(component:Person){
        self.component = component
    }
    
    override func show(){
        if component != nil {
            component!.show()
        }
    }
}
//具体的服装类(ConcreteDecorator)
class TShirts: Finery {
    override func show() {
        print("大T恤")
        super.show()
    }
}

class BigTrouser: Finery {
    override func show() {
        print("垮裤")
        super.show()
    }
}

class Sneakers: Finery {
    override func show() {
        print("球鞋")
        super.show()
    }
}

class Suit: Finery {
    override func show() {
        print("西装")
        super.show()
    }
}

class Tie: Finery {
    override func show() {
        print("领带")
        super.show()
    }
}

class LeatherShoes: Finery {
    override func show() {
        print("皮鞋")
        super.show()
    }
}

客户端代码

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let wz = Person(name: "旺仔")
        print("第一种装扮:")
        let dtx = TShirts()
        let kk = BigTrouser()
        let pqx = Sneakers()
        pqx.decorate(wz)
        kk.decorate(pqx)
        dtx.decorate(kk)
        dtx.show()
        /*
         第一种装扮:
         大T恤
         垮裤
         球鞋
         装扮的 旺仔
         */
        print("第二种装扮:")
        let xz = Suit()
        let ld = Tie()
        let px = LeatherShoes()
        px.decorate(wz)
        ld.decorate(px)
        xz.decorate(ld)
        xz.show()
        /*
         第二种装扮:
         西装
         领带
         皮鞋
         装扮的 旺仔
         */
        print("第三种装扮:")
        let pqx2 = Sneakers()
        let px2 = LeatherShoes()
        let kk2 = BigTrouser()
        let ld2 = Tie()
        pqx2.decorate(wz)
        px2.decorate(pqx2)
        kk2.decorate(px2)
        ld2.decorate(kk2)
        ld2.show()
        /*
         第三种装扮:
         领带
         垮裤
         皮鞋
         球鞋
         装扮的 旺仔
         */
    }
}

以我目前的理解, 装饰模式就是层层嵌套, 一层套一层 如果嵌套错了的话就会出现第三种装扮的情况

``

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 需求 写一个给人模拟搭配不同服饰的程序,可以给人换各种各样的衣服裤子的形象。 初步实现 需求比较简单,直接上代码:...
    Mr丶sorrow阅读 777评论 0 2
  • 1 概述 在一个项目中,你会有非常多的因素考虑不到,特别是业务的变更,不时的冒出一个需求是很正常的情况。有三个继承...
    今晚打肉山阅读 312评论 0 0
  • (转载)原文地址 在阎宏博士的《JAVA与模式》一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又...
    zjk_00阅读 652评论 0 2
  • 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。 类型 结构型 简介 装饰...
    lyu571阅读 579评论 0 2
  • 本周的状态非常不好,单位工作繁忙,我身体不适,再加上儿子不听话,整个人处于没精打采的状态。就像现在,好容易哄儿子睡...
    windy天意晚晴阅读 9,577评论 111 325