設計模式(二)-創建者模式(4)-原型模式

一、為何需要原型模式(Prototype Pattern)?

在軟件設計中,我們會遇到到這樣的情況:對原對象進行拷貝一個新的副本。想要實現這樣的邏輯,有一種笨方法就是對原對象里的所有變量進行逐一賦值。但是這樣的做法會導致代碼臃腫,邏輯復雜,還可能會有遺漏某些變量沒有被賦值的問題。

為了解決這個在代碼中對每一個變量進行賦值的問題,同時又保證能夠實現拷貝的功能,于是原型模式就出來了。

定義: 用一個已經創建的實例作為原型,來創建一個與原型對象相同的新對象

【角色】

  • 抽象原型類: 規定具體原型對象必須實現的clone()方法
  • 實現原型類: 實現抽象原型類的clone()方法。

原型模式分為淺克隆和深克隆

淺克隆(淺拷貝):創建一個新的對象,新對象的屬性和原型對象的完全相同。對對象里的引用類型成員,仍指向原來所指向的內存地址。(這里屬性指的是:值類型。同下)

深克隆(深拷貝):創建一個新對象,對對象里的屬性和引用類型成員都會被克隆,引用類型成員不再指向原來的地址。

應用條件:

  • 對象里有非常多成員,尤其該對象的引用類型成員里還有其他的引用類型對象。

二、例子

需求:
假設有一盞燈A,然后另一盞燈B根據A燈的樣子造出來的。可以說這兩盞燈外觀一摸一樣。在黑暗中,要想實現一個能有照明系統的用途,這兩盞燈還需要連接一塊電池才能發光照明。

假定電池為引用類型成員,A燈和B燈屬于值類型成員。
A燈+電池 = 原對象。
B燈 +電池 = 新對象。

現有兩種情況可以選擇:
1)情況(淺拷貝):為了節約電池的成本,把這兩盞燈都連接在同一塊電池。
2)情況(深拷貝):為了這兩盞燈要完全分開互不影響,一盞燈連接一塊電池,所以需要兩塊容量一致的電池。

Serializable: 序列化,只對深拷貝有作用。系統遍歷原對象里所有引用類型成員進行逐一克隆,無需代碼來處理具體的過程。被標記為 Serializable 的類才能夠使用深拷貝機制,否則程序運行會崩潰。

//引用類型:電池類[Serializable]public class Battery{public int Capacity;}//燈的原型抽象類[Serializable]public abstract class LampPrototype{public abstract int Use();public abstract LampPrototype ShallowClone();//淺拷貝public abstract LampPrototype DeepClone();//深拷貝}//燈的實現類[Serializable]public class Lamp : LampPrototype{//引用類型,電池public Battery battery = new Battery();public override int Use(){return battery.Capacity;}//淺拷貝public override LampPrototype ShallowClone(){return (Lamp)this.MemberwiseClone();}//深拷貝public override LampPrototype DeepClone(){MemoryStream stream = new MemoryStream();BinaryFormatter formatter = new BinaryFormatter();formatter.Serialize(stream, this);stream.Position = 0;return (Lamp)formatter.Deserialize(stream);}}class Program{//設置原對象的數據public static void setOriginal(LampPrototype lampPro) {var lamp = lampPro as Lamp;lamp.battery.Capacity = 100;}//設置新對象的數據public static void setNew(LampPrototype lampPro) {var lamp = lampPro as Lamp;lamp.battery.Capacity = 80;Console.WriteLine("New Capacity::80");}static void Main(string[] args){//原對象LampPrototype Originallamp = new Lamp();setOriginal(Originallamp);//淺拷貝Console.WriteLine();Console.WriteLine("After ShallowCopy,Original:");LampPrototype shallowAudio = Originallamp.ShallowClone();setNew(shallowAudio);//新對象使用電池,原對象的電池容量受到影響Console.WriteLine("Original Capacity:" + Originallamp.Use());//恢復原對象數據setOriginal(Originallamp);//深拷貝Console.WriteLine();Console.WriteLine("After DeepCopy,Original:");LampPrototype deepAudio = Originallamp.DeepClone();setNew(deepAudio);//新對象使用電池,原對象的電池容量沒有受到影響Console.WriteLine("Original Capacity:" + Originallamp.Use());Console.ReadLine();}}

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

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

相關文章

【SpringCloud】認識微服務、服務拆分以及遠程調用

SpringCloud 1.認識微服務 1.1單體架構 單體架構:將業務的所有功能集中在一個項目中開發,打成一個包部署 單體架構的優缺點: **優點:**架構簡單,部署成本低 **缺點:**耦合度高(維護困難&…

【C++】郭老二博文之:C++目錄

1、POCO 【POCO】POCO學習總結(一)–下載與編譯 【POCO】POCO學習總結(二)——配置選擇 【POCO】POCO學習總結(三)——交叉編譯 2、C11 2.1 STL算法 【C】C11 STL算法(一):非修改序列操作&a…

筆記59:序列到序列學習Seq2seq

本地筆記地址:D:\work_file\(4)DeepLearning_Learning\03_個人筆記\3.循環神經網絡\第9章:動手學深度學習~現代循環神經網絡 a a a a a a a a a a a a a a a

C++ Day04 this指針,友元函數,重載

this指針 概念 誰調用 this 所在的函數 ,this 就存儲誰的地址 特點 1, 在當前類的非靜態成員函數中調用本類非靜態成員時 , 默認有 this 關鍵字 2, 靜態成員函數 , 沒有 this 指針。 示例 #include <iostream> #include <cstring> using namespace std; class S…

前后端分離項目跨域請求的問題與解決辦法

目錄 一、為什么會存在跨域請求&#xff1f; 二、跨域請求的流程&#xff1f; 三、什么情況下會觸發CROS機制&#xff1f; 四、如何解決跨域請求導致的問題&#xff1f; 一、為什么會存在跨域請求&#xff1f; 跨域請求是因為瀏覽器的同源策略引起的。同源策略是瀏覽器的一種…

算法刷題-動態規劃2

算法刷題-動態規劃2 珠寶的最高價值下降路徑最小和 珠寶的最高價值 題目 大佬思路 多開一行使得代碼更加的簡潔 移動到右側和下側 dp[ i ][ j ]有兩種情況&#xff1a; 第一種是從上面來的禮物最大價值&#xff1a;dp[ i ][ j ] dp[ i - 1 ][ j ] g[ i ][ j ] 第二種是從左…

10.10-11 科研記錄 一些多模態工作的相關思考

論文出發點很簡單&#xff0c;第一&#xff0c;就是想要去除文本的冗余數據&#xff0c;有多篇文章也提到了&#xff0c;冗余文本影響對下游任務的性能&#xff0c;大量無關的文本輸入到大模型也會影響大模型的性能&#xff0c;本質也很好理解&#xff0c;就是盡可能去除與任務…

握住音樂的法寶 - 簡譜

簡譜是音樂學習中至關重要的記譜法。除了簡譜&#xff0c;還有吉他和鋼琴的五線譜&#xff0c;以及我最喜歡的古琴減字譜等其他記譜方式。如果你對音樂感興趣&#xff0c;一起學習吧&#xff0c;我不允許你是一個文盲。 一、調拍號 “1C 4/4”即為調拍號&#xff0c;調拍號分…

opencv-直方圖均衡化

直方圖均衡化是一種用于增強圖像對比度的圖像處理技術。它通過調整圖像的灰度級別分布&#xff0c;使得圖像中各個灰度級別的像素分布更均勻&#xff0c;從而提高圖像的對比度。 在OpenCV中&#xff0c;你可以使用cv2.equalizeHist()函數來進行直方圖均衡化。 以下是一個簡單…

opencv-2D直方圖

cv2.calcHist() 是 OpenCV 中用于計算直方圖的函數。它可以計算一維或多維直方圖&#xff0c;用于分析圖像中像素值的分布。 基本的語法如下&#xff1a; hist cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])參數說明&#xff1a; images:…

[點云分割] 條件歐氏聚類分割

介紹 條件歐氏聚類分割是一種基于歐氏距離和條件限制的點云分割方法。它通過計算點云中點與點之間的歐氏距離&#xff0c;并結合一定的條件限制來將點云分割成不同的區域或聚類。 在條件歐氏聚類分割中&#xff0c;通常會定義以下兩個條件來判斷兩個點是否屬于同一個聚類&…

Java繼承中的屬性名相同但是類型不同的情況

如果子類出現一個屬性與父類的屬性名一樣,那么父類的屬性將會被隱藏(java官方文檔) 在繼承當中,子類繼承父類的屬性和繼承方法的方式上有所差別: 父類屬性不可被重寫,只會被調用,父類方法可以被重寫,也可以被調用 當子類中存在和父類同名屬性,父類屬性會隱藏起來,在多態的情…

利用Python進行數據分析【送書第六期:文末送書】

&#x1f468;?&#x1f393;博主簡介 &#x1f3c5;云計算領域優質創作者 ??&#x1f3c5;華為云開發者社區專家博主 ??&#x1f3c5;阿里云開發者社區專家博主 &#x1f48a;交流社區&#xff1a;運維交流社區 歡迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

vue實現愛心形狀的復選框

目錄 HTML代碼&#xff1a; CSS代碼&#xff1a; Vue代碼&#xff1a; 這個例子使用了CSS來創建一個愛心形狀的復選框&#xff0c;并使用Vue來控制其選中狀態。點擊復選框時&#xff0c;將調用toggleChecked方法來切換checked屬性的值&#xff0c;以控制復選框的狀態。 以下…

7.vue3項目(七):品牌管理頁面的增刪改查

目錄 1.靜態頁面 2.查詢功能實現 (1)設置出參入參類型 (2)編寫查詢接口

SpringBoot——》配置logback日志文件

推薦鏈接&#xff1a; 總結——》【Java】 總結——》【Mysql】 總結——》【Redis】 總結——》【Kafka】 總結——》【Spring】 總結——》【SpringBoot】 總結——》【MyBatis、MyBatis-Plus】 總結——》【Linux】 總結——》【MongoD…

目標檢測原理

一、什么是目標檢測 目標檢測的任務是找出圖像中所有感興趣的目標&#xff08;物體&#xff09;&#xff0c;確定他們的類別和位置&#xff0c;是計算機視覺領域的核心問題之一。由于各類物體有不同的外觀、形狀、姿態&#xff0c;再加上光照、遮擋等因素的干擾&#xff0c;目…

Spring Framework 6.1 正式發布

Spring Framework 6.1.0 現已從 Maven Central 正式發布&#xff01;6.1 一代有幾個關鍵主題&#xff1a; 擁抱 JDK 21 LTS虛擬線程&#xff08;Project Loom&#xff09;JVM 檢查點恢復&#xff08;項目 CRaC&#xff09;重新審視資源生命周期管理重新審視數據綁定和驗證新的…

LeetCode207.課程表

看完題我就想&#xff0c;這不就是進程里面的死鎖問題嘛&#xff0c;進程1等進程2釋放鎖&#xff0c;進程2等進程3釋放鎖&#xff0c;進程3等進程1釋放鎖&#xff0c;這就造成了死鎖。或者是spring中的循環依賴問題&#xff0c;BeanA的初始化需要初始化一個BeanB&#xff0c;Be…