【「別跟我不會」系列】Java設計模式之原型模式
- 2019 年 10 月 8 日
- 筆記
想了解其它設計模式的歡迎關注本公眾號聯繫小編獲得相關內容。 —— 23號老闆
0
1
引入
原創:愛吃回鍋肉的瘦子
原型模式是用於創建重複對象,同時保證性能,一般應用場景是我們需要重複創建多個對象,例如在循環體中賦值一個對象。原型模式是用於創建重複對象,同時保證性能,一般應用場景是我們需要重複創建多個對象,例如在循環體中賦值一個對象。
0
2
思路
它是通過給出一個原型對象來指明所創建得對象的類型,然後使用自身的克隆介面來複制這個原型對象,以此來創建出更多同種類型的對象。
0
3
程式碼
//實現Cloneable 介面的原型抽象類 cloneTypeTest class CloneTypeTest implements Cloneable { //重寫clone方法 @Override protected CloneTypeTest clone() throws
CloneNotSupportedException {
CloneTypeTest cloneTypeTest = null; cloneTypeTest = (CloneTypeTest) super.clone();
return cloneTypeTest; } } //實現原型類 class ChildCloneTypeTest extends CloneTypeTest { public void show() { System.out.println("原型實現類"); } } class Client { public static void main(String[] args) { ChildCloneTypeTest childCloneTypeTest =
new ChildCloneTypeTest(); for (int i = 0; i < 10; i++) { try { ChildCloneTypeTest cp =
(ChildCloneTypeTest) childCloneTypeTest.clone(); cp.show(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } }
0
4
實現核心
1. 實現Cloneable介面:與序列化介面的作用相似,只是告訴虛擬機可以安全的使用clone方法,否則會拋出CloneNotSupportedException的異常。
2. 重寫父類Object的clone方法,作用是返回一個copy。
3. 在重寫的方法中調用super.clone:默認情況下,類不具備複製對象的能力,需要調用super.clone方法。父類的clone方法是naive方法,直接操作記憶體的二進位流,特別是複製大對象時,性能差異非常明顯。當然了這邊的clone形式也可以自定義,比如使用序列化形式(可以解決Cloneable淺拷貝問題)。
Clone方法的注意問題:
調用super.clone方法之後,首先檢查當前對象是否支援clone,也就是檢查當前對象所屬的類是否實現了Cloneable介面,如果支援則創建當前對象所屬的類的一個新對象並初始化,使新對象的成員變數的值與當前對象的成員變數的值一模一樣,但是對於其他對象的引用以及list等類型的成員屬性,是只能複製這些對象的引用。所以簡單使用super.clone是淺拷貝。對於淺拷貝帶來了一個問題,就是當前對象a里的有個成員變數是指向了一個對象 b,這個b對象里的屬性改變了,會引起對象a的clone對象里的b對象也會跟著改變。因此 我們在使用原型模式時候,一定要注釋清楚,這個問題,防止下一個接手的程式設計師忽視了這個坑的存在。當然了 我們可以使用深拷貝來解決這個問題,而深拷貝就是基於淺拷貝來遞歸實現具體的每個對象。
0
5
應用場景
在一些重複創建對象的場景下,例如一個循環體重複創建同一個對象,我們就可以使用原型模式來提高對象的創建性能。尤其是循環上萬次,大對象的情況下,使用new和使用原型模式性能差異非常明顯。
不信的話,各位看客老爺親自可以試驗一下。
Spring框架中的使用:其中註解@Scope(「prototype」)為原型模式。