日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java设计模式——原型模式

發布時間:2025/3/20 java 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java设计模式——原型模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

? 原型模式是為了解決一些不必要的對象創建過程。當Java JDK中提供了Cloneable接口之后,原型模式就變得異常的簡單了。雖然由于Cloneable的引入使用程序變得更簡單了,不過還是有一些需要說明和注意的東西在里面的。文本就詳細講解一下這些注意事項吧。

?

版權說明

著作權歸作者所有。
商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
本文作者:Q-WHai
發表日期: 2016年3月3日
本文鏈接:https://qwhai.blog.csdn.net/article/details/50787390
來源:CSDN
更多內容:分類 >> 設計模式

?

拷貝技術詳解

1.對象賦值

? 如果現在有一個Student對象s1,當我們使用s2=s1的方式對s2進行賦值時,實則是將s1對象的引用復制給了s2。過程如下:

圖-1 對象賦值內存分析圖

? 所以,對于s1與s2它們所指內存應該為同一塊區域。下面為此兩個“對象”所占用的內存地址:

?

org.design.pattern.prototype.model.Student@659e0bfd org.design.pattern.prototype.model.Student@659e0bfd

?

2.淺拷貝

? 什么是淺拷貝?淺拷貝后的結果是對象的內存地址變化了(對象的引用發生了變化),可對象中包含的對象內存則沒有變化。

圖-2 對象拷貝內存分析圖

? 大家看到上面的分析圖是不是有一些疑惑?為什么name發生了變化,而friends卻沒有變化呢?

? 這里先不用說其他的數據類型(int, double, char, short, long, float, byte),我們知道String類型的對象是不可變對象,當我們對不可變對象進行賦值時,它會另外開辟一個新對象。因為這個特性可能會影響到我們對Cloneable的正確判斷,所以這里需要使用一個可變對象來進行實驗。我選擇的是:List。

? 假使初始狀態是:s1有兩個朋友,小紅和小梅。當我們使用List的可變性向s2的朋友List中添加了一個新朋友時,理論上只是s2的朋友被修改了,可是實事上并非如此,以下為實驗結果:

?

初始的List對象: s1.friends: [小紅, 小梅] s2.friends: [小紅, 小梅]不改變List對象: s1.friends: [小紅, 小梅, 小剛] s2.friends: [小紅, 小梅, 小剛]重新對List對象賦值: s1.friends: [小紅, 小梅, 小剛] s2.friends: null

? 從實驗中我們可以看到如果我們對可變對象進行對象內部的可變操作時,拷貝的對象和被拷貝的對象都會被修改。單從這一點,我們就可以斷定,Cloneable的拷貝屬于淺拷貝。你是不是要問了,那怎么樣才能實現對象的深拷貝呢?請接著往下看。

?

?

?

3.深拷貝

? 上面說到對象的淺拷貝,在拷貝中我們對可變對象的操作有一些棘手。而深拷貝則可以解決這個問題。深拷貝的實現要依賴與對象的持久化操作。更多關于對象持久化的內容可參見本人另一篇博客:《網絡爬蟲:基于對象持久化實現爬蟲現場快速還原》。

? 對象持久化是說把一個對象寫到文件中(或是向網絡,或是向進程之間進行傳輸),當我們需要拷貝一個對象時,先把此對象固化到文件,再從文件中讀取對象。這樣一個過程就完成了對象的深拷貝,在博客《網絡爬蟲:基于對象持久化實現爬蟲現場快速還原》中我也有詳細地說明,這里就不再贅述了。

?

原型模式實現

? 終于可以說本文的主題(原型模式)了。

? 原型模式是基于對象的拷貝的,可以是淺拷貝也可以是深拷貝操作。也就是說當我們需要批量生成某一對象,就可以事先創建一個對象的原型,再通過對象的拷貝操作批量生成對象。原型模式的實現類圖如下:

圖-3 原型模式類圖

?

?

性能測試

這里我們測試一下原型模式的性能。

?

public static void pressureTesting() throws CloneNotSupportedException {int times = 100000000;Student student = new Student("小明");student.addFriend(new People("Friend-A"));student.addFriend(new People("Friend-B"));student.addFriend(new People("Friend-C"));student.addFriend(new People("Friend-D"));student.addFriend(new People("Friend-E"));long startStamp = System.currentTimeMillis();for (int i = 0; i < times; i++) {student.clone();}long currentStamp = System.currentTimeMillis();System.out.println("TIME USED: " + (currentStamp - startStamp) + " ms");startStamp = System.currentTimeMillis();for (int i = 0; i < times; i++) {Student student2 = new Student("小紅");student2.addFriend(new People("Friend-A"));student2.addFriend(new People("Friend-B"));student2.addFriend(new People("Friend-C"));student2.addFriend(new People("Friend-D"));student2.addFriend(new People("Friend-E"));}currentStamp = System.currentTimeMillis();System.out.println("TIME USED: " + (currentStamp - startStamp) + " ms");} 運行結果:
? TIME USED: 1752 ms TIME USED: 4352 ms 從上面的運行結果可以看出,這里如果使用 new 進行構建新對象,在性能上要慢不少。這是因為 clone 是直接針對內存操作的。但是,這里也有一個問題,對于 array 數組而言,因為這是一個淺拷貝的操作,所以還要對 array 進行特殊處理,不然可能就會導致所有對象的 array 是同一個對象。

Ref

  • 《23種Java設計模式》
  • 《編寫高質量代碼 : 改善Java程序的151個建議》

?

Github源碼下載

https://github.com/qwhai/design-pattern

?

征集

如果你也需要使用ProcessOn這款在線繪圖工具,可以使用如下邀請鏈接進行注冊:
https://www.processon.com/i/56205c2ee4b0f6ed10838a6d

總結

以上是生活随笔為你收集整理的Java设计模式——原型模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。