創建型模式之原型模式

一、概述

1、工作原理:將一個原型對象傳給要發動創建的對象(即客戶端對象),這個要發動創建的對象通過請求原型對象復制自己來實現創建過程

2、通過克隆方法所創建的對象是全新的對象,它們在內存中擁有新的地址,每一個克隆對象都是獨立

3、核心思想:是通過復制現有對象的原型來創建對象,而不是通過實例化來創建對象。

二、原型模式的結構

原型模式包含以下3個角色

(1)Prototype(抽象原型類)

(2)ConcretePrototype(具體原型類)

(3)Client(客戶類)

三、淺克隆與深克隆

1、淺克隆:當原型對象被復制時,只復制它本身和其中包含的值類型的成員變量,而引用類型的成員變量并沒有復制

?2、深克隆:除了對象本身被復制外,對象所包含的所有成員變量也將被復制

四、模式優點?

1、簡化對象的創建過程,通過復制一個已有實例可以提高新實例的創建效率

2、擴展性較好

3、提供了簡化的創建結構,原型模式中產品的復制是通過封裝在原型類中的克隆方法實現的,無須專門的工廠類來創建產品

五、模式缺點

1、需要為每一個類配備一個克隆方法,而且該克隆方法位于一個類的內部,當對已有的類進行改造時,需要修改源代碼,違背了開閉原則

2、在實現深克隆時需要編寫較為復雜的代碼,而且當對象之間存在多重嵌套引用時,為了實現深克隆,每一層對象對應的類都必須支持深克隆,實現起來可能會比較麻煩

六、模式適用環境

1、創建對象成本較大,新對象可以通過復制已有對象來獲得,如果是相似對象,則可以對其成員變量稍作修改

2、系統要保存對象的狀態,而對象的狀態變化很小

3、需要避免使用分層次的工廠類來創建分層次的對象,并且類的實例對象只有一個或很少幾個組合狀態,通過復制原型對象得到新實列可能比使用構造函數創建一個新實例更加方便

七、原型模式示例代碼

#include <iostream>
#include <map>
using namespace std;
class Prototype
{
public:virtual Prototype* clone() const = 0;virtual void showInfo() const = 0;
};class Car : public Prototype
{
public:Car(const string& make, const string& model, int year): m_make(make), m_model(model), m_year(year){}void showInfo() const override{cout << m_year << " " << m_make << " " << m_model << endl;}protected:Prototype* clone() const override{return new Car(m_make, m_model, m_year);}private:string m_make;string m_model;int m_year;
};class PrototypeFactory
{
public:Prototype* getPrototype(const string& type){return m_prototypes[type]->clone();}void addPrototype(const string& type, Prototype* prototype){m_prototypes[type] = prototype;}
private:map<string, Prototype*> m_prototypes;
};int main()
{PrototypeFactory factory;Car* carPrototype = new Car("Honda", "Accord", 2024);factory.addPrototype("Car", carPrototype);Prototype* cloneCar = factory.getPrototype("Car");carPrototype->showInfo();cloneCar->showInfo();return 0;
}

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

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

相關文章

MySQL 中的 varchar 和 char 有什么區別?MySQL中 in 和 exists 區別?

MySQL 中的 varchar 和 char 有什么區別&#xff1f; char 是一個定長字段,假如申請了char(10)的空間,那么無論實際存儲多少內容.該字段都占用 10 個字符,而 varchar 是變長的,也就是說申請的只是最大長度,占用的空間為實際字符長度1,最后一個字符存儲使用了多長的空間. 在檢索…

李沐動手學習深度學習——3.6練習

本節直接實現了基于數學定義softmax運算的softmax函數。這可能會導致什么問題&#xff1f;提示&#xff1a;嘗試計算exp(50)的大小。 可能存在超過計算機最大64位的存儲&#xff0c;導致精度溢出&#xff0c;影響最終計算結果。 本節中的函數cross_entropy是根據交叉熵損失函數…

JavaScript之數據類型

系列文章目錄 文章目錄 系列文章目錄前言 前言 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站&#xff0c;這篇文章男女通用&#xff0c;看懂了就去分享給你的碼吧。 數據類型   Java…

20.圖

圖的基本概念 1.圖的定義 由頂點和邊組成的集合&#xff0c;G(V,E) 2.基本概念 鄰接點&#xff1a; 對于無向圖u v來說&#xff0c;uv互為鄰接點 對于有向圖u->v來說&#xff0c;v是u的鄰接點&#xff0c;但u不是v的臨界點 路徑&#xff1a; 一個頂點到另一個頂點所經過的…

從Poincare猜想看中國數學的國際地位

2006年丘成桐學派利用北京晨興數學中心&#xff0c;宣布一名俄國學者Poincare猜想研究中存在錯誤&#xff0c;已經由華裔學者朱熹平和曹懷東糾正過來&#xff0c;但數年以后我發現作為千禧七問題之一的Poincazre猜想&#xff0c;英國克萊數學所還是把1百萬美元獎金送給俄國人。…

藍橋杯:卡片

題目 小藍有很多數字卡片&#xff0c;每張卡片上都是數字0 到9。 小藍準備用這些卡片來拼一些數&#xff0c;他想從1 開始拼出正整數&#xff0c;每拼一個&#xff0c;就保存起來&#xff0c;卡片就不能用來拼其它數了。 小藍想知道自己能從1 拼到多少。 例如&#xff0c;當小…

動態規劃-最長公共子串(c)

動態規劃 動態規劃&#xff08;dynamic programming&#xff09;是一種算法設計方法。基本思想是在對一個問題的多階段決策中&#xff0c;按照某一順序&#xff0c;根據每一步所選決策的不同&#xff0c;會引起狀態的轉移&#xff0c;最后會在變化的狀態中獲取到一個決策序列。…

vs code更新后json文件無法識別通配符 ,編譯多文件失敗的解決辦法

問題描述 在Mac或者LInux上&#xff0c;進行C/C相同路徑下進行多文件編譯時&#xff0c;之前設置好的json文件突然不能解釋通配符&#xff0c;并且將帶有單引號的地址傳給clang&#xff0c;由于*.c被擴在單引號中&#xff0c;clang找不到文件導致失敗。 如果將命令端中的指令復…

云服務器無法Ping通解決

問題: 使用公網IP地址PING云服務器,無法PING通 但是可SSH到服務器,表示通信鏈路是正常的,可能是端口或路徑規則未開放導致 登陸云服務器后臺,進行安全組規則查看,發現ICMP沒有放行 添加允許ICMP連接規則 成功PING通云服務器

LeetCode——二叉樹(Java)

二叉樹 簡介[簡單] 144. 二叉樹的前序遍歷、94. 二叉樹的中序遍歷、145. 二叉樹的后序遍歷二叉樹層序遍歷[中等] 102. 二叉樹的層序遍歷[中等] 107. 二叉樹的層序遍歷 II[中等] 199. 二叉樹的右視圖[簡單] 637. 二叉樹的層平均值[中等] 429. N 叉樹的層序遍歷[中等] 515. 在每個…

Java接口

接口的定義 抽象方法的集合&#xff0c;接口通常以interface來聲明。一個類通過繼承接口的方式&#xff0c;從而來繼承接口的抽象方法。 接口并不是類&#xff0c;編寫接口的方式和類很相似&#xff0c;但是他們屬于不同的概念。類描述的是對象的屬性和方法。接口則包含類要實…

AcWing 4726. 尋找數字

解題思路 在這個二插搜索樹中尋找&#xff0c;4和7數量相等&#xff0c;并且大于n的最小數。 相關代碼 import java.util.*;public class Main {static String s;static List<Integer> res new ArrayList<>();static long n;static long ansLong.MAX_VALUE;publ…

遞歸實現指數型枚舉(c++題解)

題目描述 從 1~n 這 n(n<16) 個整數中隨機選取任意多個&#xff0c;輸出所有可能的選擇方案。 輸入格式 一個整數n。 輸出格式 每行一種方案。同一行內的數必須升序排列&#xff0c;相鄰兩個數用恰好1個空格隔開。對于沒有選任何數的方案&#xff0c;輸出空行。 樣例 …

python 爬蟲 app爬取之charles的使用

專欄系列:http://t.csdnimg.cn/WfCSx 前言 前面介紹的都是爬取 Web 網頁的內容。隨著移動互聯網的發展,越來越多的企業并沒有提供 Web 網頁端的服務,而是直接開發了 App,更多更全的信息都是通過 App 來展示的。那么針對 App 我們可以爬取嗎?當然可以。 App 的爬取相比 …

使用HTML5畫布(Canvas)模擬圖層(Layers)效果

使用HTML5畫布&#xff08;Canvas&#xff09;模擬圖層&#xff08;Layers&#xff09;效果 在圖形處理和計算機圖形學中&#xff0c;圖層&#xff08;Layers&#xff09;是指將圖像分成不同的可獨立編輯、組合和控制的部分的技術或概念。每個圖層都可以包含不同的圖形元素、效…

18.題目:編號760 數的計算

題目&#xff1a; ###該題主要考察遞推、遞歸 將該題看成若干個子問題 #include<bits/stdc.h> using namespace std; const int N20; int a[N];int dfs(int dep){int res1;for(int i1;i<a[dep-1]/2;i){a[dep]i;resdfs(dep1);}return res; }int main(){int n;cin>…

python并發 map函數的妙用

1.map是什么&#xff1f; map函數是Python中的一個內置函數&#xff0c;用于將一個函數應用到一個或多個可迭代對象的每個元素上&#xff0c;生成一個新的可迭代對象。它的一般形式是&#xff1a; map(function, iterable1, iterable2, ...)其中&#xff0c;function是一個函…

解決GCC連接器(lld)出現問題 relocation truncated to fit (重定向截斷)

本文大致提點這個問題&#xff0c;有哪些可行的解決方案。 這是常見 C/C 的一類連接器錯誤&#xff0c;我們需要知道它一般是怎么產生的&#xff0c;才能知道如何正確的解決它。 例如&#xff1a;&#xff08;當發生這類問題時&#xff0c;連接器通常會輸出這樣的信息&#x…

《Spring Security 簡易速速上手小冊》第8章 常見問題與解決方案(2024 最新版)

文章目錄 8.1 異常處理和日志記錄8.1.1 基礎知識詳解8.1.2 重點案例&#xff1a;統一異常處理案例 Demo拓展 8.1.3 拓展案例 1&#xff1a;日志記錄策略案例 Demo拓展 8.1.4 拓展案例 2&#xff1a;日志聚合案例 Demo拓展 8.2 多租戶安全性問題8.2.1 基礎知識詳解8.2.2 重點案例…

深入Kafka client

分區分配策略 客戶端可以自定義分區分配策略, 當然也需要考慮分區消費之后的offset提交, 是否有沖突。 消費者協調器和組協調器 a. 消費者的不同分區策略, 消費者之間的負載均衡(新消費者加入或者存量消費者退出), 需要broker做必要的協調。 b. Kafka按照消費組管理消費者, …