装饰模式

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

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

人物类

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

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

``

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

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