模式定義
用原型實例指定創建對象的種類,并且通過復制這些原型創建新的對象,其允許一個對象再創建
另外一個可定制的對象,無須知道任何創建的細節
- 對象創建型模式
基本工作原理是通過將一個原型對象傳給那個要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝原型自己來實現創建過程
模式結構
- Prototype:抽象原型類
- 在Java中可以直接使用Object,其提供clone()方法實現對象的克隆
- 一般而言,clone()方法滿足:
- 對任何的對象x,都有x.clone() !=x,即克隆對象與原對象不是同一個對象
- 對任何的對象x,都有x.clone().getClass() == x.getClass(),即克隆對象與原對象的類型一樣
- 如果對象x的equals()方法定義恰當,那么有x.clone().equals(x) == true
- 一般而言,clone()方法滿足:
- 在Java中可以直接使用Object,其提供clone()方法實現對象的克隆
- ConcretePrototype:具體原型類
- 能夠實現克隆的Java類必須實現一個標識接口Cloneable,表示這個Java類支持復制
- 如果一個類沒有實現這個接口但是調用了clone()方法,Java編譯器將拋出一個CloneNotSupportedException異常
- Client:客戶類
public class PrototypeDemo implements Cloneable {......public Object clone() {Object object = null;try {object = super.clone();} catch (CloneNotSupportedException exception) {System.err.println("Not support cloneable");}return object;}......}
- 深克隆
- 使用原型模式克隆對象時,其成員對象也克隆
- 淺克隆
- 使用原型模式克隆對象時,其成員對象不克隆
帶原型管理器的原型模式
模式分析
- 優點
- 當創建新的對象實例較為復雜時,使用原型模式可以簡化對象的創建過程,通過一個已有實例可以提高新實例的創建效率
- 可以動態增加或減少產品類
- 原型模式提供了簡化的創建結構
- 可以使用深克隆的方式保存對象的狀態
- 缺點
- 需要為每一個類配備一個克隆方法,而且這個克隆方法需要對類的功能進行通盤考慮,對已有的類進行改造時可能修改其源代碼
- 違背開閉原則
- 在實現深克隆時需要編寫較為復雜的代碼
- 需要為每一個類配備一個克隆方法,而且這個克隆方法需要對類的功能進行通盤考慮,對已有的類進行改造時可能修改其源代碼
適用環境
- 創建新對象成本較大,新的對象可以通過原型模式對已有對象進行復制來獲得
- 如果是相似對象,則可以對其屬性稍作修改
- 如果系統要保存對象的狀態,而對象的狀態變化很小,或者對象本身占內存不大的時候,也可以使用原型模式配合備忘錄模式來應用
- 相反,如果對象的狀態變化很大,或者對象占用的內存很大,那么采用狀態模式會比原型模式更好
- 需要避免使用分層次的工廠類來創建分層次的對象,并且類的實例對象只有一個或很少的幾個組合狀態,通過復制原型對象得到新實例可能比使用構造函數創建一個新實例更加方便。