ios-装饰器模式

1,274 阅读2分钟
  • 具体的对象学生基本属性是名字和身份
  • 但是现在有个要求就是学生在校必须穿校服,在外面可以不穿
  • 方案一就是改造学生给学生添加一个衣服的成员属性来设置,但是假如我们这个学生类是很复杂的一个类了,很多的成员属性一个个加上去就很臃肿了,
  • 就比如说这个学生在兼职的时候必须带上工作牌,还要加上工作牌属性,但是并不是所有学生都要工作牌属性。
  • 装饰模式(Decorator),动态地为一个对象添加额外的职责,是继承的替代方案,属于结构型模式。通过装饰模式扩展对象的功能比继承子类方式更灵活,使用继承子类的方式,是在编译时静态决定的,即编译时绑定,而且所有的子类都会继承相同的行为。然而,如果使用组合的方式扩展对象的行为,就可以在运行时动态地进行扩展,将来如果需要也可以动态的撤销,而不会影响原类的行为。
  • 其实很好理解为 A模型多个成员变量,B模型中有A模型+自己特有的成员变量,这样就能减轻A模型的不断的添加带来的臃肿。
// 角色-: 具体组件 学生
class Student{
    
    var name: String
    var profession: String
    
    init(name: String) {
        self.name = name
        self.profession = "学生"
    }
}
  • 学生校服类
import Foundation

// 角色二: 具体的装饰者 服饰
class StudentClothes {
    var student : Student
    var clothes: String?
    
    init(student: Student) {
        self.student = student
        self.clothes = "校服"
    }
    var name: String {
        set {
            self.student.name = newValue
        }
        get {
            return self.student.name
        }
    }
    var profession: String {
        set {
            self.student.profession = newValue
        }
        get {
            return self.student.profession
        }
    }

    
    func printClothes() {
        print("我叫\(self.name), 我是一个\(self.profession), 我今天穿了\(self.clothes ?? "")")
    }
}
  • 学生打工工作牌类
import Foundation
class StudentJob {
    var student : Student
    var jobCard: String?
    
    init(student: Student) {
        self.student = student
        self.jobCard = "工作牌"
    }
    var name: String {
        set {
            self.student.name = newValue
        }
        get {
            return self.student.name
        }
    }
    var profession: String {
        set {
            self.student.profession = newValue
        }
        get {
            return self.student.profession
        }
    }

    func printClothes() {
        print("我叫\(self.name), 我是一个\(self.profession), 我今天穿了\(self.jobCard ?? "")")
    }
}
  • 调用
let student = Student(name: "李四")
student.printStudent()
let clothes = StudentClothes(student: student)
clothes.printClothes()

let jobs = StudentJob(student: student)
jobs.printClothes()

  • 结果
    • 我叫李四, 我是一个学生
    • 我叫李四, 我是一个学生, 我今天穿了校服
    • 我叫李四, 我是一个学生, 我今天穿了工作牌