六.原型模式

一.原型模式的定義

????????原型模式是一種創建型設計模式,通過復制現有對象(原型)生成新對象,避免重復初始化成本。需了解以下關鍵概念:

  • ?淺拷貝?:復制基本類型字段,引用類型字段共享內存地址(修改新對象會影響原對象)。
  • ?深拷貝?:遞歸復制引用對象(如通過序列化/手動復制),新舊對象完全獨立。

二.實現方式

2.1.?Java 原生實現(了解)

實現Cloneable接口,聲明對象可以被克隆。Cloneable接口是個空接口,有僅有標志作用

通過Object的clone()方法復制現有對象生成新實例,而非通過構造函數創建,默認是淺拷貝。

也可以深拷貝,但是需要手動賦值,且需處理異常,本章不演示。

2.1.1.案例

/*** 使用 Cloneable 接口實現淺拷貝* 注意:只復制了對象本身,未復制內部的 List 字段** 該類演示了 Java 原生 Cloneable 接口的使用方式。* clone() 方法調用 super.clone(),僅復制對象自身,不復制引用字段(如 List)* 因此,克隆后的對象與原對象共享同一個 List 實例,修改其中一個會影響另一個。* 適用于對象結構簡單、無需深拷貝的場景。** @author demo*/
public class ShallowCloneWithCloneable implements Cloneable {private String name;private List<String> tags = new ArrayList<>();public ShallowCloneWithCloneable(String name) {//注意:String是不可變的,所以淺克隆和深克隆效果一致this.name = name;//賦默認值,方便查看是否被可弄this.tags.add("default");}@Overridepublic ShallowCloneWithCloneable clone() {try {return (ShallowCloneWithCloneable) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}public void addTag(String tag) {tags.add(tag);}public void display() {System.out.println("Name: " + name);System.out.println("Tags: " + tags);}
}public static void main(String[] args) {// 創建原始對象ShallowCloneWithCloneable original = new ShallowCloneWithCloneable("Original Object");System.out.println("原始對象:");original.display();// 克隆對象ShallowCloneWithCloneable copy = original.clone();System.out.println("克隆對象:");copy.display();// 修改克隆對象的引用字段System.out.println("修改克隆對象的 tags...");copy.addTag("new-tag");// 查看原始對象是否受影響System.out.println("原始對象現在的狀態:");original.display();System.out.println("克隆對象現在的狀態:");copy.display();}

?2.2.2.運行結果

原始對象:
Name: Original Object
Tags: [default]
克隆對象:
Name: Original Object
Tags: [default]
修改克隆對象的 tags...
原始對象現在的狀態:
Name: Original Object
Tags: [default, new-tag]
克隆對象現在的狀態:
Name: Original Object
Tags: [default, new-tag]

2.2.序列化與反序列化機制實現

2.2.1.案例

/*** 使用序列化與反序列化機制實現深拷貝* 注意:所有字段都會被重新創建,包括引用類型字段** 該類演示了如何通過 Java 的序列化和反序列化機制實現真正的深拷貝。* 對象及其所有引用字段都會被完全復制,確保克隆后的對象與原對象完全獨立。* 適用于復雜對象的深拷貝,無需手動復制字段。* 要求類必須實現 Serializable 接口。** @author demo*/
public class SerializableDeepClone implements Serializable {private String name;private List<String> tags = new ArrayList<>();public SerializableDeepClone(String name) {this.name = name;this.tags.add("default");}/*** 深拷貝方法* @return 一個新的、獨立的對象副本*/public SerializableDeepClone clone() {try {// 序列化ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);// 反序列化ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (SerializableDeepClone) ois.readObject();} catch (Exception e) {throw new RuntimeException("深拷貝失敗", e);}}public void addTag(String tag) {tags.add(tag);}public void display() {System.out.println("Name: " + name);System.out.println("Tags: " + tags);}
}public static void main(String[] args) {// 創建原始對象SerializableDeepClone original = new SerializableDeepClone("Original Object");System.out.println("原始對象:");original.display();// 克隆對象SerializableDeepClone copy = original.clone();System.out.println("\n克隆對象:");copy.display();// 修改克隆對象的引用字段System.out.println("\n修改克隆對象的 tags...");copy.addTag("new-tag");// 查看原始對象是否受影響System.out.println("\n原始對象現在的狀態:");original.display();System.out.println("\n克隆對象現在的狀態:");copy.display();}

2.2.2.運行結果

原始對象:
Name: Original Object
Tags: [default]

克隆對象:
Name: Original Object
Tags: [default]

修改克隆對象的 tags...

原始對象現在的狀態:
Name: Original Object
Tags: [default]

克隆對象現在的狀態:
Name: Original Object
Tags: [default, new-tag]

2.3.?SerializationUtils實現

2.3.1.案例

<!--引入依賴-->    
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version>
</dependency>
/*** 使用 Apache Commons 的 SerializationUtils.clone() 實現深拷貝* 注意:所有字段都會被重新創建,包括引用類型字段** 該類演示了如何通過 Apache Commons Lang 提供的 SerializationUtils.clone() 方法實現真正的深拷貝。* 對象及其所有引用字段都會被完全復制,確保克隆后的對象與原對象完全獨立。* 適用于復雜對象的深拷貝,簡化開發并避免手動復制字段。* 要求類必須實現 Serializable 接口。** @author demo*/
public class SerializableWithUtilsClone implements Serializable {private String name;private List<String> tags = new ArrayList<>();public SerializableWithUtilsClone(String name) {this.name = name;this.tags.add("default");}/*** 深拷貝方法,使用 Apache Commons Lang 的 SerializationUtils.clone()* @return 一個新的、獨立的對象副本*/public SerializableWithUtilsClone deepCopy() {return SerializationUtils.clone(this);}public void addTag(String tag) {tags.add(tag);}public void display() {System.out.println("Name: " + name);System.out.println("Tags: " + tags);}
}public static void main(String[] args) {// 創建原始對象SerializableWithUtilsClone original = new SerializableWithUtilsClone("Original Object");System.out.println("原始對象:");original.display();// 克隆對象SerializableWithUtilsClone copy = original.deepCopy();System.out.println("克隆對象:");copy.display();// 修改克隆對象的引用字段System.out.println("修改克隆對象的 tags...");copy.addTag("new-tag");// 查看原始對象是否受影響System.out.println("原始對象現在的狀態:");original.display();System.out.println("克隆對象現在的狀態:");copy.display();}

2.3.2.運行結果

原始對象:
Name: Original Object
Tags: [default]
克隆對象:
Name: Original Object
Tags: [default]
修改克隆對象的 tags...
原始對象現在的狀態:
Name: Original Object
Tags: [default]
克隆對象現在的狀態:
Name: Original Object
Tags: [default, new-tag]

💡 如果本文對你有幫助,點擊右上角【訂閱專欄】或左上角關注我 ?
🔔 完整的23中設計模式干貨,第一時間推送給你!
🔔 有什么問題也可以在評論區討論🤝🤝🤝?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86595.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86595.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86595.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【筆記】LoRA 理論與實現|大模型輕量級微調

論文鏈接&#xff1a;LoRA: Low-Rank Adaptation of Large Language Models 官方實現&#xff1a;microsoft/LoRA 非官方實現&#xff1a;huggingface/peft、huggingface/diffusers 這篇文章要介紹的是一種大模型/擴散模型的微調方法&#xff0c;叫做低秩適應&#xff08;也就是…

Cilium動手實驗室: 精通之旅---15.Isovalent Enterprise for Cilium: Network Policies

Cilium動手實驗室: 精通之旅---15.Isovalent Enterprise for Cilium: Network Policies 1. 環境信息2. 測試環境部署3. 默認規則3.1 測試默認規則3.2 小測驗 4. 網絡策略可視化4.1 通過可視化創建策略4.2 小測試 5. 測試策略5.1 應用策略5.2 流量觀測5.3 Hubble觀測5.4 小測試 …

opencv RGB圖像轉灰度圖

這段代碼的作用是將一個 3通道的 RGB 圖像&#xff08;CV_8UC3&#xff09;轉換為灰度圖像&#xff08;CV_8UC1&#xff09;&#xff0c;并使用 OpenCV 的 parallel_for_ 對圖像處理進行并行加速。 &#x1f50d; 一、函數功能總結 if (CV_8UC3 img.type()) {// 創建灰度圖 d…

React Hooks 的原理、常用函數及用途詳解

1. ??Hooks 是什么&#xff1f;?? Hooks 是 React 16.8 引入的函數式組件特性&#xff0c;允許在不編寫 class 的情況下使用 state 和其他 React 特性&#xff08;如生命周期、副作用等&#xff09;。??本質是一類特殊函數??&#xff0c;它們掛載到 React 的調度系統中…

學習路之PHP--webman協程學習

學習路之PHP--webman協程學習 一、準備二、配置三、啟動四、使用 協程是一種比線程更輕量級的用戶級并發機制&#xff0c;能夠在進程中實現多任務調度。它通過手動控制掛起和恢復來實現協程間的切換&#xff0c;避免了進程上下文切換的開銷 一、準備 PHP > 8.1 Workerman &g…

linux libusb使用libusb_claim_interface失敗(-6,Resource busy)解決方案

linux libusb使用libusb_claim_interface失敗&#xff08;-6&#xff0c;Resource busy&#xff09;解決方案 ? 問題原因&#x1f6e0;? 解決方案&#x1f538; 方法一&#xff1a;分離內核驅動 libusb_detach_kernel_driver()&#x1f538; 方法二&#xff1a;使用 usb-devi…

使用mpu6500/6050, PID,互補濾波實現一個簡單的飛行自穩控制系統

首先&#xff0c;參考ai給出的客機飛機的比較平穩的最大仰府&#xff0c;偏轉&#xff0c;和防滾角度&#xff0c;如下&#xff1a; 客機的最大平穩仰俯&#xff08;Pitch&#xff09;、偏轉&#xff08;Yaw&#xff09;和防滾&#xff08;Roll&#xff09;角度&#xff0c;通…

深度解析AD7685ARMZRL7:16位精密ADC在低功耗系統中的設計價值

產品概述 AD7685ARMZRL7是16位逐次逼近型&#xff08;SAR&#xff09;ADC&#xff0c;采用MSOP-10緊湊封裝。其核心架構基于電荷再分配技術&#xff0c;支持2.3V至5.5V單電源供電&#xff0c;集成低噪聲采樣保持電路與內部轉換時鐘。器件采用偽差分輸入結構&#xff08;IN/-&a…

EXCEL 實現“點擊跳轉到指定 Sheet”的方法

&#x1f4cc; WPS 表格技巧&#xff1a;如何實現點擊單元格跳轉到指定 Sheet 在使用 WPS 表格&#xff08;或 Excel&#xff09;時&#xff0c;我們經常會希望通過點擊一個單元格&#xff0c;直接跳轉到工作簿中的另一個工作表&#xff08;Sheet&#xff09;。這在制作目錄頁…

Python格式化:讓數據輸出更優雅

Python格式化&#xff1a;讓數據輸出更優雅 Python的格式化功能能讓數據輸出瞬間變得優雅又規范。不管是對齊文本、控制數字精度&#xff0c;還是動態填充內容&#xff0c;它都能輕松搞定。 一、基礎格式化&#xff1a;從簡單拼接開始 1. 百分號&#xff08;%&#xff09;格式…

2025年滲透測試面試題總結-小鵬[實習]安全工程師(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 小鵬[實習]安全工程師 1. 自我介紹 2. 有沒有挖過src&#xff1f; 3. 平時web滲透怎么學的&#xff0c;有…

VSCode科技風主題設計詳細指南

1. 科技風設計的核心特點 科技風設計是一種強調未來感、現代感和高科技感的設計風格,在VSCode主題設計中,可以通過以下幾個核心特點來體現: 1.1 色彩特點 冷色調為主:藍色、紫色、青色等冷色調是科技風設計的主要色彩高對比度:深色背景配合明亮的霓虹色,形成強烈的視覺…

android知識總結

Activity啟動模式 standard (標準模式) 每次啟動該 Activity&#xff08;例如&#xff0c;通過 startActivity()&#xff09;&#xff0c;系統總會創建一個新的實例&#xff0c;并將其放入調用者&#xff08;啟動它的那個 Activity&#xff09;所在的任務棧中。 singleTop (棧…

第3章 MySQL數據類型

MySQL數據類型 1、數字數據類型1.1 整數類型1.2 定點類型1.3 浮點類型1.4位值類型1.5 超出范圍和溢出處理1.5.1 超出范圍處理1.5.2 溢出處理 2、日期和時間數據類型3、字符串數據類型3.1 char和varchar類型3.2 binary和varbinary類型3.3 blob 和 text類型3.4 enum類型3.4.1 創建…

label-studio的使用教程(導入本地路徑)

文章目錄 1. 準備環境2. 腳本啟動2.1 Windows2.2 Linux 3. 安裝label-studio機器學習后端3.1 pip安裝(推薦)3.2 GitHub倉庫安裝 4. 后端配置4.1 yolo環境4.2 引入后端模型4.3 修改腳本4.4 啟動后端 5. 標注工程5.1 創建工程5.2 配置圖片路徑5.3 配置工程類型標簽5.4 配置模型5.…

mysql為什么一個表中不能同時存在兩個字段自增

背景。設置sort自增。會引發錯誤 通常自增字段都是用于表示數據的唯一性。數據庫限制。需要自定義排序字段大小。

牛客round95D

原題鏈接&#xff1a;D-小紅的區間修改&#xff08;一&#xff09;_牛客周賽 Round 95 題目背景&#xff1a; 初始擁有一個長度10^100元素全為0的數組&#xff0c;進行q查詢&#xff0c;每次查詢如果區間內的元素都為0就將區間變為首項為 1、公差為 1 的等差數列&#xff1b;否…

visual studio 2022更改主題為深色

visual studio 2022更改主題為深色 點擊visual studio 上方的 工具-> 選項 在選項窗口中&#xff0c;選擇 環境 -> 常規 &#xff0c;將其中的顏色主題改成深色 點擊確定&#xff0c;更改完成

實踐篇:利用ragas在自己RAG上實現LLM評估②

文章目錄 使用ragas做評估在自己的數據集上評估完整代碼代碼講解1. RAG系統構建核心組件初始化文檔處理流程 2. 評估數據集構建3. RAGAS評估實現1. 評估數據集創建2. 評估器配置3. 執行評估 本系列閱讀&#xff1a; 理論篇&#xff1a;RAG評估指標&#xff0c;檢索指標與生成指…

微軟PowerBI考試 PL300-在 Power BI 中清理、轉換和加載數據

微軟PowerBI考試 PL300-在 Power BI 中清理、轉換和加載數據 Power Query 具有大量專門幫助您清理和準備數據以供分析的功能。 您將了解如何簡化復雜模型、更改數據類型、重命名對象和透視數據。 您還將了解如何分析列&#xff0c;以便知曉哪些列包含有價值的數據&#xff0c;…