《大话设计模式》第 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.
总结
如果构造新对象的执行效率很低效,在初始化信息不发生变化的情况下,克隆是最好的办法。