美文网首页
Design Patterns Talk - Decorator

Design Patterns Talk - Decorator

作者: su3 | 来源:发表于2017-04-01 11:52 被阅读0次

    《大话设计模式》第 6 章 - 装饰模式 的 Swift 实现。

    问题

    对一个人进行装扮,衣服、鞋子、领带等等,考虑不同的人有不同装扮,并且便于增加装扮。

    方案

    把装饰功能按特性的不同拆分到各自单独的子类中,交给交互端根据需要进行组合搭配,每个装饰类传入上一个装饰完成之后的对象,这样就能把用户选择的装饰串联起来,完成最终的装饰,同时装饰类随时可以添加,不影响已有的装饰。

    1. Component,定义一个接口协议,抽象化装饰组件

    protocol Person{
        func show()
    }
    

    2. ConcreteComponent 类,定义具体的对象,也可以给这个对象添加一些职责

    class SimplePerson: Person{
        private let name: String
        
        init(name: String){
            self.name = name
        }
        
        func show(){
            print("装扮的 \(name) ")
        }
    }
    

    3. Decorator,装饰类,遵循 Component 协议。Component 无需知道 Decorator 的存在。

    required 关键字要求子类必须传入装饰过的对象。并在装饰方法中执行实例对象的核心方法。

    class PersonDecorator: Person{
        
        let decoratedPerson: Person
        
        required init(decorated: Person){
            self.decoratedPerson = decorated
        }
        
        func show() {
            decoratedPerson.show()
        }
    }
    

    4. ConcreteDecorator,具体的装饰器,实现 component 要的职责。

    Decorator 的子类,初始化方法中传入一个已装饰的对象,依次应用装饰类,就可以把用到的装饰组合起来。

    final class Tee: PersonDecorator{
        
        required init(decorated: Person) {
            super.init(decorated: decorated)
        }
    
        override func show() {
            print("T恤", separator: "", terminator: " ")
            super.show()
        }
    }
    
    final class BeachShorts: PersonDecorator{
        
        required init(decorated: Person) {
            super.init(decorated: decorated)
        }
        
        override func show() {
            print("沙滩裤", separator: "", terminator: " ")
            super.show()
        }
    }
    
    final class Sunglasses: PersonDecorator{
        
        required init(decorated: Person) {
            super.init(decorated: decorated)
        }
        
        override func show() {
            print("墨镜", separator: "", terminator: " ")
            super.show()
        }
    }
    

    测试

    var someone: Person = SimplePerson(name: "Tom") //即将被装饰的对象,可以有一些基础属性
    someone = Tee(decorated: someone) //用 Tee 去装饰 someone
    someone = BeachShorts(decorated: someone) //在上一步装饰好之后继续装饰
    someone = Sunglasses(decorated: someone) //继续用 Sunglasses 去装饰前两步装饰过的对象
    
    someone.show()
    

    输出

    墨镜 沙滩裤 T恤 装扮的 Tom 
    

    总结

    装饰模式是为已有功能动态添加更多功能的一种方式。把每个装饰功能放在单独的类中,并用这个类包装它所要装饰的对象。客户代码可以根据需要有选择地使用装饰功能来依次包装对象,可以以随意的顺序组合装饰。

    这样有效地把类的核心功能和装饰功能区分开。要增加装饰时不需要改动任何已有代码。

    playground

    相关文章

      网友评论

          本文标题:Design Patterns Talk - Decorator

          本文链接:https://www.haomeiwen.com/subject/aoriottx.html