23種設計模式(二)原型模式

用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。java

1.定義編程

用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。設計模式

Prototype原型模式是一種建立型設計模式,Prototype模式容許一個對象再建立另一個可定製的對象,根本無需知道任何如何建立的細節,工做原理是:經過將一個原型對象傳給那個要發動建立的對象,這個要發動建立的對象經過請求原型對象拷貝它們本身來實施建立。數組

2.問題和解決方案緩存

當對象的構造函數很是複雜,在生成新對象的時候很是耗時間、耗資源的狀況?咱們是怎麼來建立呢?安全

 經過複製(克隆、拷貝)一個指定類型的對象來建立更多同類型的對象。這個指定的對象可被稱爲「原型」對象,也就是經過複製原型對象來獲得更多同類型的對象。即原型設計模式。如clone函數

3.結構ui

http://my.csdn.net/uploads/201203/26/1332722887_7899.jpg

客戶(Client)角色:使用原型對象的客戶程序this

抽象原型(Prototype)角色:規定了具體原型對象必須實現的接口(若是要提供深拷貝,則必須具備實現clone的規定).net

具體原型(ConcretePrototype):從抽象原型派生而來,是客戶程序使用的對象,即被複制的對象。此角色須要實現抽象原型角色所要求的接口。

原型模式主要用於對象的複製,它的核心是就是類圖中的原型類Prototype。Prototype類須要具有如下兩個條件:

  • 實現Cloneable接口。在java語言有一個Cloneable接口,它的做用只有一個,就是在運行時通知虛擬機能夠安全地在實現了此接口的類上使用clone方法。在java虛擬機中,只有實現了這個接口的類才能夠被拷貝,不然在運行時會拋出CloneNotSupportedException異常。
  • 重寫Object類中的clone方法。Java中,全部類的父類都是Object類,Object類中有一個clone方法,做用是返回對象的一個拷貝,可是其做用域protected類型的,通常的類沒法調用,所以,Prototype類須要將clone方法的做用域修改成public類型。

實現代碼

  1. class Prototype implements Cloneable {  
  2.     public Prototype clone(){  
  3.         Prototype prototype = null;  
  4.         try{  
  5.             prototype = (Prototype)super.clone();  
  6.         }catch(CloneNotSupportedException e){  
  7.             e.printStackTrace();  
  8.         }  
  9.         return prototype;   
  10.     }  
  11. }  
  12.   
  13. class ConcretePrototype extends Prototype{  
  14.     public void show(){  
  15.         System.out.println("原型模式實現類");  
  16.     }  
  17. }  
  18.   
  19. public class Client {  
  20.     public static void main(String[] args){  
  21.         ConcretePrototype cp = new ConcretePrototype();  
  22.         for(int i=0; i< 10; i++){  
  23.             ConcretePrototype clonecp = (ConcretePrototype)cp.clone();  
  24.             clonecp.show();  
  25.         }  
  26.     }  
  27. }  

4.優缺點

優勢:

Prototype模式有許多和Abstract Factory模式 和 Builder模式同樣的效果:它對客戶隱藏了具體的產品類,所以減小了客戶知道的名字的數目。此外,這些模式使客戶無需改變便可使用與特定應用相關的類。
1 ) 運行時刻增長和刪除產品: Prototype容許只經過客戶註冊原型實例就能夠將一個新的具體產品類併入系統。它比其餘建立型模式更爲靈活,由於客戶能夠在運行時刻創建和刪除原型。
2 ) 改變值以指定新對象: 高度動態的系統容許你經過對象複合定義新的行爲—例如,經過爲一個對象變量指定值—而且不定義新的類。你經過實例化已有類而且將這些實例註冊爲客戶對象的原型,就能夠有效定義新類別的對象。客戶能夠將職責代理給原型,從而表現出新的行爲。這種設計使得用戶無需編程便可定義新「類」 。實際上,克隆一個原型相似於實例化一個類。Prototype模式能夠極大的減小系統所須要的類的數目。
3) 改變結構以指定新對象:許多應用由部件和子部件來建立對象。
4) 減小子類的構造 Factory Method 常常產生一個與產品類層次平行的 Creator類層次。Prototype模式使得你克隆一個原型而不是請求一個工廠方法去產生一個新的對象。所以你根本不須要Creator類層次。
5) 用類動態配置應用 一些運行時刻環境容許你動態將類裝載到應用中。

5.深拷貝與淺拷貝

http://my.csdn.net/uploads/201204/28/1335593679_5601.png

 

淺拷貝:

被拷貝對象的全部變量都含有與原對象相同的值,並且對其餘對象的引用仍然是指向原來的對象。即淺拷貝只負責當前對象實例,對引用的對象不作拷貝。

淺複製後的對象和對象副本的狀況:

http://my.csdn.net/uploads/201204/28/1335593768_4314.png

深拷貝:

被拷貝對象的全部的變量都含有與原來對象相同的值,除了那些引用其餘對象的變量。那些引用其餘對象的變量將指向一個被拷貝的新對象,而再也不是原有那些被引用對象。即 深拷貝把要拷貝的對象所引用的對象也都拷貝了一次,而這種對被引用到的對象拷貝叫作間接拷貝。

深複製的對象和對象副本的狀況:

http://my.csdn.net/uploads/201204/28/1335594139_6714.jpg

6.注意事項

  • 使用原型模式複製對象不會調用類的構造方法。由於對象的複製是經過調用Object類的clone方法來完成的,它直接在內存中複製數據,所以不會調用到類的構造方法。不但構造方法中的代碼不會執行,甚至連訪問權限都對原型模式無效。還記得單例模式嗎?單例模式中,只要將構造方法的訪問權限設置爲private型,就能夠實現單例。可是clone方法直接無視構造方法的權限,因此,單例模式與原型模式是衝突的,在使用時要特別注意。
  • 深拷貝與淺拷貝。Object類的clone方法只會拷貝對象中的基本的數據類型,對於數組、容器對象、引用對象等都不會拷貝,這就是淺拷貝。若是要實現深拷貝,必須將原型模式中的數組、容器對象、引用對象等另行拷貝。例如:
  •     private ArrayList list = new ArrayList();  
  •     public Prototype clone(){  
  •         Prototype prototype = null;  
  •         try{  
  •             prototype = (Prototype)super.clone();  
  •             prototype.list = (ArrayList) this.list.clone();  
  •         }catch(CloneNotSupportedException e){  
  •             e.printStackTrace();  
  •         }  
  •         return prototype;   
  •     }  
  • }  

因爲ArrayList不是基本類型,因此成員變量list,不會被拷貝,須要咱們本身實現深拷貝,幸運的是java提供的大部分的容器類都實現了Cloneable接口。因此實現深拷貝並非特別困難。

PS:深拷貝與淺拷貝問題中,會發生深拷貝的有java中的8中基本類型以及他們的封裝類型,另外還有String類型。其他的都是淺拷貝。

7.使用場景

原型模式的主要思想是基於現有的對象克隆一個新的對象出來,通常是有對象的內部提供克隆的方法,經過該方法返回一個對象的副本,這種建立對象的方式,相比咱們以前說的幾類建立型模式仍是有區別的,以前的講述的工廠模式與抽象工廠都是經過工廠封裝具體的new操做的過程,返回一個新的對象,有的時候咱們經過這樣的建立工廠建立對象不值得,特別是如下的幾個場景的時候,可能使用原型模式更簡單也效率更高。

1. 當一個系統應該獨立於他的產品建立、構成和表示時,須要使用原型模式

2. 當要實例化的類是在運行時刻指定時,如經過動態裝載

3. 爲了不建立一個與產品類層次平行的工廠類層次時

4. 當一個類的實例只能有幾個不一樣狀態組合中的一種時,創建相應數目的原型並克隆他們可能比每次用合適的狀態手工實例化該類更方便一些。

8.總結

1.原型模式比較容易理解,實現一個接口(Cloneable ),重寫一個方法(clone)即完成了原型模式。在實際應用中,原型模式不多單獨出現。常常與其餘模式混用,他的原型類Prototype也經常使用抽象類來替代。

2.原型分爲淺拷貝和深拷貝,淺拷貝是對原對象的引用,深拷貝會新生成一個對象地址。

3.原型模式節省建立對象的時間,能夠保存原型到緩存中。

相關文章
相關標籤/搜索