原型設計模式
- 一 .簡介
- 二. 案例
- 三. 補充知識
前言
這是我在這個網站整理的筆記,有錯誤的地方請指出,關注我,接下來還會持續更新。
作者:神的孩子都在歌唱
一 .簡介
原型模式提供了一種機制,可以將原始對象復制到新對象,然后根據我們的需要進行修改。原型設計模式使用java克隆來復制對象。
原型模式的克隆分為淺克隆和深克隆。
深拷貝(Deep Copy)和淺拷貝(Shallow Copy)是指在進行對象復制時所產生的兩種不同結果。
深拷貝:創建一個新對象,新對象的屬性和原來對象完全相同,對于非基本類型屬性,仍指向原有屬性所指向的對象的內存地址。
淺拷貝:創建一個新對象,屬性中引用的其他對象也會被克隆,不再指向原有對象地址。
Java中的Object類中提供了 clone()
方法來實現淺克隆。 Cloneable 接口是上面的類圖中的抽象原型類,而實現了Cloneable接口的子實現類就是具體的原型類。
二. 案例
通過一個例子就很容易理解原型設計模式。假設我們有一個從數據庫加載數據的對象。現在我們需要在程序中多次修改這些數據,因此使用通過new 一個新的對象,并再次從數據庫加載所有數據并不是一個好主意。更好的方法是將現有對象克隆到新對象中,然后進行數據操作。原型設計模式其實就是需要你確保正在拷貝的對象應該提供拷貝功能。它不應該由任何其他類完成。然而,是否使用對象屬性的淺拷貝或 深拷貝 取決于 需求及其設計決策。
以下是代碼案例:
這里我定義了一個籃球類,通過重新實現clone方法來實現深拷貝
/*** @author chenyunzhi*/
public class Ball implements Cloneable{private final List<String> ballList;public Ball(){ballList = new ArrayList<>();}public Ball(List<String> ballList){this.ballList=ballList;}/*** 模擬從數據庫中拿數據*/public void loadData(){ballList.add("basketball");ballList.add("soccer");}public List<String> getBallList() {return ballList;}@Overridepublic Ball clone() throws CloneNotSupportedException {return new Ball(new ArrayList<>(this.getBallList()));}}
然后我寫了一個測試類方便測試,這里我new了一個 ball 對象,然后對ball對象進行拷貝,對拷貝的對象進行了增添和刪除他們相互之間都不影響
/*** @author chenyunzhi*/
public class PrototypePatternTest {public static void main(String[] args) throws CloneNotSupportedException {Ball ball = new Ball();ball.loadData();Ball ballNew =ball.clone();Ball ballNew1 = ball.clone();List<String> list = ballNew.getBallList();list.add("tennis");List<String> list1 = ballNew1.getBallList();list1.remove("basketball");// 輸入修改后的球類列表System.out.println("ball List: "+ball.getBallList());System.out.println("ballNew List: "+list);System.out.println("ballNew1 List: "+list1);System.out.println("ball List: "+ball.getBallList());}}
測試結果
結論:如果沒有提供對象克隆,我們每次都必須調用數據庫來獲取球類列表。然后進行那些耗費資源和時間的操作。這就是java中原型設計模式的全部內容。
三. 補充知識
問題: 為什么淺拷貝中 拷貝的對象修改了某個String類型的值,被拷貝對象的值沒有變化?
在Java類庫中,所有基本類型的包裝類都是不可變類,例如Integer、Float等。
不可變類(Immutable Class) 在初始化后的所有信息不能被修改。而更改String成員的值相當于在堆中新建一個String引用,舊的String常量引用仍然存在于堆中,只不過還沒回收,從而讓兩個引用不相等。這時你以為String是被克隆,但造成其不相等的原因其實是賦值。
作者:神的孩子都在歌唱
本人博客:https://blog.csdn.net/weixin_46654114
轉載說明:務必注明來源,附帶本人博客連接。