設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。GoF提出了23種設計模式,本系列將使用Swift語言來實現這些設計模式。
概述
通過複製一個已存在的對象來獲得一個新的相同類型的對象被稱作原型模式,在複製的過程中不需要關心被複制對象實現的接口或者類型。
原型模式Prototype具有如下優點:
隱藏了創建對象的實現細節
複製操作不受子類構造器改變影響
避免了重複創建對象產生的大量代碼
簡單來說,原型模式分爲以下兩種:
簡單拷貝
登記拷貝
沒有使用原型Prototype的拷貝代碼是怎樣的呢?我們需要通過訪問
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Pet: NSObject { var name: String? var weigh: Float? init(name: String, weigh: Float) { ... } } class Person: NSObject { var pet: Pet? var name: String? var height: Float? init(name: String, height: Float, pet: Pet) { ... } } let pet = Pet(name: "球球" , weigh: 2.0) let author = Person(name: "林欣達" , height: 173, pet: pet) var persons: [Person] = [Person]() for _ in 0...9 { persons.append(Person(name: author.name!, height: author.height!, pet: Pet(name: pet.name, weigh: pet.weigh))) } |
簡單形式拷貝
通過聲明一個Cloning協議來爲需求方提供完全拷貝的方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | protocol Cloning { func clone() -> AnyObject } class Pet: NSObject, Cloning { func clone() -> AnyObject { return Pet(name: name!, weigh: weigh!) } } class Person: NSObject, Cloning { func clone() -> AnyObject { return Person(name: name!, height: height! pet: pet?.clone() as! Pet) } } let author = Person(name: "林欣達" , height: 173, pet: Pet(name: "球球" , weigh: 2.0)) var persons: [Person] = [Person]() for _ in 0...9 { persons.append(author.clone()) } |
簡單點來說,原型模式在iOS開發中就是NSCopying協議,通過實現這個協議完成對象和其成員對象的完全內存拷貝,也可以稱爲深拷貝。從這個角度而言,原型模式Prototype就是深拷貝的理論化
登記拷貝
登記拷貝實際上就是在簡單拷貝的基礎之上對這些clone對象進行管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class CloneManager: NSObject { static let sharedManager = CloneManager() private var mapper: [String: Cloning] = [String: Cloning]() private override init() { super .init() } func store(prototype: Cloning, for identifier: String) { mapper[identifier] = prototype } func prototype( for identifier: String) -> Cloning? { return mapper[identifier] } func remove( with identifier: String) { mapper[identifier] = nil } } class ViewController: UIViewController { override func viewDidLoad() { let clone = author.clone() CloneManager.sharedManager.store(clone, "CloneInstance" ) let storedClone = CloneManager.sharedManager.prototype( for : "CloneInstance" ) if clone == storedClone { print( "Store success" ) } if clone != author { print( "You create a copy instance of author" ) } CloneManager.sharedManager.remove( with : "CloneInstance" ) assert( CloneManager.sharedManager.prototype( for : "CloneInstance" ) == nil ) } } |
總結
原型模式Prototype將對象和其成員對象的拷貝過程隱藏起來,只提供了一個簡單的接口提供我們獲取拷貝後的對象,是一種優雅而強大的設計。使用原型模式需要注意實現Cloning的對象其成員對象也應該遵循這個協議提供簡單的拷貝接口。