装饰模式

2016-03-30  本文已影响29人  旺仔Milk

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

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

人物类

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()
        /*
         第三种装扮:
         领带
         垮裤
         皮鞋
         球鞋
         装扮的 旺仔
         */
    }
}

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

``

上一篇 下一篇

猜你喜欢

热点阅读