原型模式——創建型模式

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

思路:

馬上又到找工作的時候了,當我們在準備一份份簡歷的時候有沒有考慮過這樣一個問題?

面對不同的工作崗位我們需要準備不同的求職簡歷,但是這樣的幾份不同的簡歷中還是有相當大的部分是相同的,我們如果每一份都從頭開始重新制作,無疑是做了很多的無用功,浪費了很多時間。

那么,我們有沒有辦法不用重新new一個簡歷,只是對某一個原件進行適當的修改,就能實現這個功能呢?

別忘了,我們是程序員呀,程序員別的不一定行,Ctrl+C和Ctrl+V還是很溜的。復制下來對需要修改的部分進行修改不就行了?

但是同樣別忘了,我們是程序員,如果這樣一個問題用程序的思維來看,又會是什么樣呢?

我們需要一個簡歷類,我們可以設置個人信息、工作經歷,并且把它們顯示出來。我們可以怎么寫呢?

    class Program{static void Main(string[] args){Resume a;a = new Resume("張三");a.SetPersonalInfo("男", "22");a.SetWorkExperience("1998-2000", "XX公司");a.SetAimCompany("Google");Resume b =  new Resume("張三");b = a;a.Display();b.Display();b.SetAimCompany("IBM");a.Display();b.Display();Console.Read();}}class Resume  //簡歷{private string name;private string sex;private string age;private string timeArea;private string company;private string AimCompany;public Resume(string name){this.name = name;}//設置個人信息public void SetPersonalInfo(string sex, string age){this.sex = sex;this.age = age;}//設置工作經歷public void SetWorkExperience(string timeArea, string company){this.timeArea = timeArea;this.company = company;}//設置個人信息public void SetAimCompany(string AimCompany){this.AimCompany = AimCompany;}//顯示public void Display(){Console.WriteLine("尊敬的" + AimCompany + "公司領導,您好:");Console.WriteLine("{0} {1} {2}", name, sex, age);Console.WriteLine("工作經歷:{0} {1}", timeArea, company);Console.WriteLine("");}}

那么由以上代碼的運行結果我們可以看到,當我們改變b的工作經歷的時候,a的工作經歷同樣改變了。這是什么原因呢?因為

b=a;

這行代碼執行的結果是,將a指向b的內容,并沒有給a分配內存空間。所以改變了b實際上改變了a指向的內容。即并沒有實現克隆的效果。

事實上,對于C#而言,因為克隆的常用,它在System命名空間里提供了ICloneable接口,其中一個惟一的方法就是Clone,我們只需要實現這個接口就好了,而不用去寫它的原型抽象類了。

    class Program{static void Main(string[] args){Resume a = new Resume("張三");a.SetPersonalInfo("男", "22");a.SetWorkExperience("1998-2000", "XX公司");a.SetAimCompany("Google");Resume b = (Resume)a.Clone() ;a.Display();b.Display();b.SetAimCompany("IBM");a.Display();b.Display();Console.Read();}}//簡歷class Resume :  ICloneable{private string name;private string sex;private string age;private string timeArea;private string company;private string AimCompany;public Resume(string name){this.name = name;}//設置個人信息public void SetPersonalInfo(string sex, string age){this.sex = sex;this.age = age;}//設置工作經歷public void SetWorkExperience(string timeArea, string company){this.timeArea = timeArea;this.company = company;}//設置個人信息public void SetAimCompany(string AimCompany){this.AimCompany = AimCompany;}//顯示public void Display(){Console.WriteLine("尊敬的" + AimCompany + "公司領導,您好:");Console.WriteLine("{0} {1} {2}", name, sex, age);Console.WriteLine("工作經歷:{0} {1}", timeArea, company);Console.WriteLine("");}public Object Clone(){return this.MemberwiseClone();//淺復制}}

有運行結果我們可以看出,對b進行改變并不會改變a的結果,即實現了克隆的效果。

但需要注意的是,這里的克隆其實只是淺克隆。

值類型在克隆的時候是逐位復制,為深復制。而引用類型在復制時不復制引用的對象,只復制引用,為淺復制。而在C#中,string類型為特殊的引用類型,他可以被當做值類型進行深復制。所以在這里只是進行淺復制就可以達到效果。

但是一旦需要克隆類類型的變量的時候,不進行深復制是不行的。例如,我們的簡歷類中有設置身份證的方法,而在實際中我們一般會有一個身份證類,其間有身份證屬性和設置身份證號的方法。這樣就需要我們提供一個對這些引用類型實現深復制的方法。

    class Program{static void Main(string[] args){Resume a = new Resume("張三");a.SetPersonalInfo("男", "22");a.SetWorkExperience("1998-2000", "XX公司");a.SetAimCompany("Google");Resume b = (Resume)a.DeepClone();a.Display();b.Display();b.SetAimCompany("IBM");b.idinfo.IdNumber = 56789;a.Display();b.Display();Console.Read();}}public class IDInfo{public int IdNumber;public IDInfo(int IdNumber){this.IdNumber = IdNumber;}}//簡歷class Resume : ICloneable{private string name;private string sex;private string age;private string timeArea;private string company;private string AimCompany;public IDInfo idinfo;public Resume(string name){this.name = name;idinfo = new IDInfo(123456);}//設置個人信息public void SetPersonalInfo(string sex, string age){this.sex = sex;this.age = age;}//設置工作經歷public void SetWorkExperience(string timeArea, string company){this.timeArea = timeArea;this.company = company;}//設置個人信息public void SetAimCompany(string AimCompany){this.AimCompany = AimCompany;}//顯示public void Display(){Console.WriteLine("尊敬的" + AimCompany + "公司領導,您好:");Console.WriteLine("{0} {1} {2}", name, sex, age);Console.WriteLine("工作經歷:{0} {1}", timeArea, company);Console.WriteLine("ID號碼:"+idinfo.IdNumber.ToString());Console.WriteLine("");}public Object Clone(){return this.MemberwiseClone();}public Object DeepClone(){Resume rsm = (Resume)this.MemberwiseClone();rsm.idinfo = new IDInfo(this.idinfo.IdNumber);return rsm;}}

以上,就是原型模式的思路和方法。

UML圖:

140154_0KYn_2725918.png

吐槽:

原型模式就是從一個對象在創建另外一個可定制的對象,而且不需知道任何創建的細節。

優點:

一般在初始化信息不發生變化的情況下,克隆是最好的辦法,這既隱藏了對象創建的細節,又對性能是大大的提高。因為它不需要從新初始化對象,而是動態的獲得對象運行時的狀態。

原型模式允許動態增加或減少產品類。

原型模式具有給一個應用軟件動態加載新功能的能力。

產品類不需要非得有任何事先確定的等級結構 。

缺點:

每一個類必須配備一個克隆方法。而且這個克隆方法需要對類的功能進行通盤考慮,這對全新的類來說不是很難,但對已有的類進行改造時,不一定是件容易的事。

在實現深克隆時需要編寫較為復雜的代碼。

使用情景:

創建新對象成本較大(CPU,初始化)。

系統要保存對象的狀態,對象狀態變化很小。

當一個類的實例只有幾個不同狀態組合時,建立相應數目的原型并克隆它們可能比每次用合適的狀態手工實例化更為方便。

?

本菜鳥的疑難雜癥:

1、在C#中類類型是引用類型,所以復制時默認淺復制。而string是一種特殊的引用類型,在處理的時候底層會把它當做值類型處理。

2、淺復制表明,被復制的對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用都仍然指向原來對象。要實現復制之后引用類型不指向同一個對象,就需要把復制的對象所引用的對象都復制一遍,即深復制。深復制把引用對象的變量指向復制過的新對象,而不是原有的被引用的對象。

轉載于:https://my.oschina.net/CoderBleak/blog/677163

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

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

相關文章

如何獲取 ASP.NET Core 當前啟動地址?

前言上次,我們介紹了配置ASP.NET Core啟動地址的多種方法。那么,如何通過代碼方式,獲取啟動后的地址?WebApplication.Urls 對象使用 WebApplication.Urls.Add 方法可以添加啟動地址。那么,使用 WebApplication.Urls 應…

【CASS精品教程】CASS9.1查詢功能大全(坐標、長度、面積、方位角)

文章目錄 1. 查詢指定點坐標2. 查詢兩點距離及方位3. 查詢線長4. 查詢實體面積CASS9.1中提供了查詢指定點坐標、查詢兩點距離及方位、查詢線長、查詢實體面積等查詢功能,如下圖所示: 本文以動畫演示的方式,對以上提到的功能進行講解。 1. 查詢指定點坐標 點擊【工程應用】…

自定義smokeping告警(郵件+短信)

前段時間接到公司IT同事需求,幫助其配置smokeping的告警功能,之前配置的姿勢有些問題,告警有些問題,現在調試OK,在此將關鍵配置點簡單記錄下。 關鍵的配置項主要有: 定義告警規則并配置將告警信息通過管道交…

WPF 實現抽屜菜單

分享一個WPF 實現抽屜菜單抽屜菜單作者:WPFDevelopersOrg原文鏈接:https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40;Visual Studio 2022;項目使用 MIT 開源許可協議;更多效果可以通過GitHub[1]|碼云[2]…

selenium 定制啟動 chrome 的選項

2019獨角獸企業重金招聘Python工程師標準>>> selenium 定制啟動 chrome 的選項 博客分類: java 搜索引擎,爬蟲 使用 selenium 時,我們可能需要對 chrome 做一些特殊的設置,以完成我們期望的瀏覽器行為,比如…

平臺級 SAAS 架構的基礎:統一身份管理系統

業內在用戶統一身份認證及授權管理領域,主要關注 4 個方面:集中賬號管理(Account)、集中認證管理(Authentication)、集中授權管理(Authorization)和集中審計管理(Audit&a…

【ArcGIS Pro微課1000例】0017:ArcGIS Pro 2.8制作炫酷的ETOPO1全球DEM地圖

ArcGIS Pro相對于ArcGIS,在制圖方面做了很大的提升,做出的地圖更加優美,本文講解基于NOAA的ETOPO1數據全球DEM數據制作炫酷的全球DEM地圖,先看效果再教學! 1. 效果展示 全球 澳大利亞大陸

Js中的for in

2019獨角獸企業重金招聘Python工程師標準>>> 后臺數據&#xff1a; List<Map<String, Object>> uTags query.selectAllList("velocity.userGetTags", map); 前端解析&#xff1a; for(var i in data.content){//由于這里是List[i](Map).IDc…

VMWare 安裝 Linux

參考 &#xff1a; http://www.aboutyun.com/thread-6780-1-1.html 這的是很詳細。贊一下 我這里就簡化一下。 1 下載&#xff1a; VMWare : https://download3.vmware.com/software/wkst/file/VMware-workstation-full-10.0.0-1295980.exe ubuntu : http://www.aboutyun…

【ArcGIS Pro微課1000例】0018:ArcGIS Pro 2.8通過OLE DB與個人數據庫建立連接案例

對于個人數據庫,Access程序可以直接打開。本文講解在ArcGIS Pro2.8中通過OLE DB與個人數據庫MDB建立聯系的方法與過程。 文章目錄 1. 個人數據庫準備2. OLE DB連接個人數據庫1. 個人數據庫準備 準備一個個人數據庫,在上面右鍵→復制文件地址。 文件地址為:"C:\test.md…

JAVA生成并導出json文件

將一個list集合轉換成json文件并導出&#xff1a; 數據集合&#xff1a;    List<Object> agencyList new ArrayList<Object>();Map<String, Object> agencyMap new HashMap<>();agencyMap.put("agencyName",agencyName);agencyMap.pu…

《ASP.NET Core 6框架揭秘》實例演示[02]:基于路由、MVC和gRPC的應用開發

ASP.NET Core可以視為一種底層框架&#xff0c;它為我們構建出了基于管道的請求處理模型&#xff0c;這個管道由一個服務器和多個中間件構成&#xff0c;而與路由相關的EndpointRoutingMiddleware和EndpointMiddleware是兩個最為重要的中間件。MVC和gRPC開發框架就建立在路由基…

什么是 JWT -- JSON WEB TOKEN

什么是JWT Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放標準&#xff08;(RFC 7519).該token被設計為緊湊且安全的&#xff0c;特別適用于分布式站點的單點登錄&#xff08;SSO&#xff09;場景。JWT的聲明一般被用來在身份提供者和服務提…

Re-installation failed due to different application signatures.

問題&#xff1a; 在虛擬設備上運行程序時提示安裝失敗。 [2010-08-08 00:38:30 - myApp] Re-installation failed due to different application signatures. [2010-08-08 00:38:30 - myApp] You must perform a full uninstall of the application. WARNING: This will remo…

【ArcGIS微課1000例】0024:ArcGIS如何連接文件夾、設認工作目錄、默認地理數據庫、相對路徑與絕對路徑?

ArcGIS軟件在初次安裝完成或者為了工作的方便,通常需要連接到指定的文件夾、設置默認工作路徑,默認地理數據庫、相對路徑與絕對路徑等。 文章目錄 1. 文件夾連接2. 默認工作目錄3. 默認地理數據庫4. 相對路徑與絕對路徑1. 文件夾連接 在初次安裝完ArcGIS時,默認沒有文件夾連…

shell 用環境變量的值修改properties文件

假設有如下屬性文件 demo.properties user.nametest user.password123456 ............................... 需求&#xff1a;先需要通過shell 腳本將 user.name 和 user.password 的value值替換為實際需要的用戶名和密碼&#xff0c; 將可以通過如下方式實現&#xff1a; sed …

【Spring Cloud】Redis緩存接入監控、運維平臺CacheCloud

CacheCloud CacheCloud提供一個Redis云管理平臺&#xff1a;實現多種類型(Redis Standalone、Redis Sentinel、Redis Cluster)自動部署、解決Redis實例碎片化現象、提供完善統計、監控、運維功能、減少運維成本和誤操作&#xff0c;提高機器的利用率&#xff0c;提供靈活的伸縮…

[Win10應用開發] 使用 Windows 推送服務 (WNS)

前言 Windows 推送服務&#xff08;WNS&#xff09;也是 Win10 通知機制中的一種&#xff0c;今天與大家一起學習一下有關WNS的相關知識。使用 Windows 推送服務的前提是你需要有一個微軟開發者賬號&#xff0c;這樣才能得到一些合法的密鑰信息用于與WNS服務器完成通訊操作。 …

Windows 11 新版 25158 推送!全新搜索框和圖標、小組件動態內容和通知標記

面向 Dev 頻道的 Windows 預覽體驗成員&#xff0c;微軟現已推送 Windows 11 預覽版 Build 25158。主要變化1.微軟宣布為 Windows 11 搜索引入全新視覺體驗&#xff0c;由搜索框或重新設計的搜索圖標呈現。目前該功能僅向部分 Windows 預覽體驗成員推出&#xff0c;將在未來向所…

Python之路【第一篇】:環境搭建

虛擬機安裝 下載VMwareWorkstation以及centos,安裝完VMwareWorkstation&#xff0c;創建一個虛擬機&#xff0c;然后在新創建的虛擬機上運行centos linux環境搭建 公司開發使用linux的原因&#xff1a;穩定、安全、開源 在虛擬機中使用centos這個版本&#xff0c;作為服務器端的…