設計模式 -- 原型模式

當克隆優於建立java

原型模式屬於對象的建立模式。經過給出一個原型對象來指明全部建立的對象的類型,而後用複製這個原型對象的辦法建立出更多同類型的對象。安全

場景

  • 當你的系統並不想關心一個對象的建立,組合的細節.
  • 一個對象須要提供給其餘對象訪問,並且各個調用者可能都須要修改其值時,能夠考慮使用原型模式拷貝多個對象供調用者使用
  • 當一個類的實例只有幾種狀態的時候,先建立好這幾種實例,須要時clone,好過每次建立新的,而後設置到合適的狀態.
  • 當建立對象的代價大於克隆

用法

原型模式要求對象實現一個能夠「克隆」自身的接口,這樣就能夠經過複製新的實例出來.
clone是Object類的方法,其實原型模式在某種程度上和java融爲一體.
有時原型模式和工廠模式結合在一塊兒,用於爲工廠創造新的對象.
在原型模式的使用中,淺拷貝和深拷貝是須要注意的地方.設計

克隆

Java的全部類都是從java.lang.Object類繼承而來的,而Object類提供protected Object clone()方法對對象進行復制,子類固然也能夠把這個方法置換掉,提供知足本身須要的複製方法。對象的複製有一個基本問題,就是對象一般都有對其餘的對象的引用。當使用Object類的clone()方法來複制一個對象時,此對象對其餘對象的引用也同時會被複制一份.對象

Java語言提供的Cloneable接口只起一個做用,就是在運行時期通知Java虛擬機能夠安全地在這個類上使用clone()方法。經過調用這個clone()方法能夠獲得一個對象的複製。因爲Object類自己並不實現Cloneable接口,所以若是所考慮的類沒有實現Cloneable接口時,調用clone()方法會拋出CloneNotSupportedException異常。繼承

克隆知足的條件:
clone()方法將對象複製了一份並返還給調用者。「複製」的含義即clone()方法是怎麼實現的。
通常而言,clone()方法知足如下的要求:接口

  1. 對任何的對象x,都有:x.clone()!=x。換言之,克隆對象與原對象不是同一個對象。
  2. 對任何的對象x,都有:x.clone().getClass() == x.getClass(),換言之,克隆對象與原對象的類型同樣。
  3. 若是對象x的equals()方法定義其恰當的話,那麼x.clone().equals(x)應當成立的。
    在JAVA語言的API中,凡是提供了clone()方法的類,都知足上面的這些條件。JAVA語言的設計師在設計本身的clone()方法時,也應當遵照着三個條件。通常來講,上面的三個條件中的前兩個是必需的,而第三個是可選的。

淺拷貝

只負責克隆按值傳遞的數據(好比基本數據類型、String類型),而不復制它所引用的對象.
換言之,全部的對其餘對象的引用都仍然指向原來的對象
Object默認的clone方式是這樣作的.get

深拷貝

除了淺度克隆要克隆的值外,還負責克隆引用類型的數據。那些引用其餘對象的變量將指向被複制過的新對象,而再也不是原有的那些被引用的對象.換言之,深度克隆把要複製的對象所引用的對象都複製了一遍,而這種對被引用到的對象的複製叫作間接複製。
深拷貝通常有兩種方式:原型

  1. 經過實現Cloneable接口,複寫clone方法,咱們能夠自定義一個對象的克隆.
  2. 經過序列化和反序列化實現克隆. 這樣作的前提就是對象以及對象內部全部引用到的對象都是可序列化的,不然,就須要仔細考察那些不可序列化的對象能否設成transient,從而將之排除在複製過程以外。
相關文章
相關標籤/搜索