Cocoa cola——Cocoa Framework之原型模式,cocoacola
在許多物件導向的應用程式中,有些對象的建立代價過大或過於複雜,此時若是可以只作輕微的改動就可以重建相同的對象,以適應程式中的特定情況,那真是極好的。比較典型的情況就是複製組合結構,比如樹型結構,從零開始構建一個樹型組合體非常困難。與建立各種跟父類差異較少的獨立類相比,讓某些對象產生自身的複製品這種做法可複用性極高並且更易於維護。
應用於“複製”操作的模式稱為原型模式,複製指用同一模具生產一系列的產品,模具所基於的物品稱為原型。原型決定了最終產品應該是什麼樣子,儘管產品是用同一模具複製的,但是某些屬性可以稍有不同。
模型圖
如果想要較好的使用原型模式,那麼有必要對淺複製和深複製有比較深刻的理解。下面我將用圖示的方式直觀方便的解析它們的異同
淺複製
如果對象有個指標型成員變數指向記憶體中的某個資源,如果只是將指標複製給新對象(副本),那麼底層的資源實際上仍然由兩個執行個體在共用。如果所示:
在ConcretePrototype的clone操作中,把資源指標的值複製到了新的副本。儘管ConcrePrototype的執行個體產生了一個同類型的執行個體作為其副本,但兩個執行個體的指標仍指向記憶體中的同一資源。這種只複製了指標值而不是實際資源,稱為淺複製。
深複製
那麼什麼是深複製呢?深複製是指不僅複製指標值,還複製指標所指向的資源,產生記憶體中實際資源的真正副本。如下:
Cocoa Touch中的對象複製
Cocoa Touch Framework為NSObject的衍生類別提供了實現深複製的協議。NSObject的子類需要實現NSCopying協議及其方法:
(id)copyWithZone:(NSZone *)zone
NSObject有一個執行個體方法叫做(id) copy,預設的copy方法調用[ self copyWithZone : nil ]。對於採納了NSCopying協議的子類,需要實現這個方法,否則將引發異常。iOS中,這個方法保持新的副本對象,然後將其返回。特別地,此方法的調用者要負責釋放返回的對象。
多數情況下,深複製的實現看起來並不很複雜。其思路是複製必需的成員變數與資源,傳給此類的新執行個體,然後返回這個新執行個體。技巧在於保證確實複製了記憶體中的資源,而不是指標值。
應用情境
在以下情形,可以考慮使用原型模式:
①、需要建立的對象應獨立於其類型與建立方式
②、要執行個體化的類是在運行時決定的
③、不想要與產品層次相對應的工廠層次
④、不同類的執行個體間的差異僅是狀態的若干組合,因此複製相應數量的原型比手工執行個體化更加方便
⑤、類不容易建立,比如每個組件可把其他組件作為子節點的組合對象。複製已有的組合對象並對副本進行修改會更加容易。