Design Patterns Talk - Prototype Pattern

《大话设计模式》第 9 章 - 原型模式 的 Swift 实现。

问题

复制简历并修改其中的某些条目。

方案

原型模式通过拷贝原型创建新的对象。从一个对象再创建另外一个可定制的对象,并且不需要知道创建的细节。

Prototype:基本原型,声明一个克隆自身的接口

protocol Cloneable{
    func clone() -> Any
}

ConcretePrototype:具体原型

实现克隆自身的操作。如果有指针类型,需要实现深复制。

class Resume{
    var name: String
    var sex: String?
    var age: String?
    
    var work: WorkExperience?
    
    
    init(name: String) {
        self.name = name
        self.work = WorkExperience()
    }
    
    func setPersonalInfo(sex: String, age: String){
        self.sex = sex
        self.age = age
    }
    
    func setWorkExperience(workDate: String, company: String){
        self.work?.workDate = workDate
        self.work?.company = company
    }
    
    func display(){
        guard let sex = sex, let age = age else {
            return
        }
        
        print("\(self.name) \(sex) \(age)")
        
        guard let workDate = work?.workDate, let company = work?.company else {
            return
        }
        
        print("\(workDate) \(company)")
    }
    
    func clone() -> Any{
        let obj = Resume(name: self.name)
        obj.sex = self.sex
        obj.age = self.age
        obj.work = self.work
        return obj
    }
}

嵌套小类

如果有嵌套的类,可以声明为 struct,在 swift 中 struct 是值类型(相对于 class 是指针类型),struct 通过复制,传递值。

struct WorkExperience{
    var workDate: String?
    var company: String?
}

测试

只要调用 clone() 方法就可以实现新简历的生成,并且可以修改新简历的细节。

let a = Resume(name: "Tom")
a.setPersonalInfo(sex: "male", age: "29")
a.setWorkExperience(workDate: "1998-2000", company: "XX Co.")

let b = a.clone() as! Resume
b.setWorkExperience(workDate: "1998-2006", company: "YY Co.")

a.display()
b.display()

输出

Tom male 29
1998-2000 XX Co.
Tom male 29
1998-2006 YY Co.

总结

如果构造新对象的执行效率很低效,在初始化信息不发生变化的情况下,克隆是最好的办法。

playground

你可能感兴趣的:(Design Patterns Talk - Prototype Pattern)