本篇內容主要講解“怎么理解Java設計模式的原型模式”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么理解Java設計模式的原型模式”吧!
單例模式可以避免重復創建消耗資源的對象,但是卻不得不共用對象。若是對象本身也不讓隨意訪問修改時,怎么辦?通常做法是備份到副本,其它對象操作副本,最后獲取權限合并,類似git上的PR操作。
原型模式用原型實例指定創建對象的種類,并通過拷貝這些原型創建新的對象。需要注意的關鍵字是,新的對象,類沒變。.NET在System命名空間中提供了Cloneable接口,其中它提供唯一的方法Clone(),只需要實現這個接口就可以完成原型模式了。由于它直接操作內存中的二進制流,當大量操作或操作復雜對象時,性能優勢將會很明顯。
多用于創建大對象,或初始化繁瑣的對象。如游戲中的背景,地圖。web中的畫布等等
以下場景適用:
一是類初始化需要消化非常多的資源,這個資源包括數據、硬件資源等;
二是通過 new 產生一個對象需要非常繁瑣的數據準備或訪問權限,則可以使用原型模式;
三是一個對象需要提供給其他對象訪問,而且各個調用者可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用。
在實際項目中,原型模式很少單獨出現,一般是和工廠方法模式一起出現,通過 clone的方法創建一個對象,然后由工廠方法提供給調用者。
以簡歷的復印來舉例
定義工作經歷類
/// <summary> /// 工作經歷類 /// </summary> public class WorkExperience { private string _workDate; public string WorkDate { get { return _workDate; } set { _workDate = value; } } private string _company; public string Company { get { return _company; } set { _company = value; } } }
定義簡歷類
/// <summary> /// 簡歷類 /// </summary> class Resume : ICloneable { private string name; private string sex; private string age; private WorkExperience work; public Resume(string name) { this.name = name; work = new WorkExperience(); } /// <summary> /// 設置個人信息 /// </summary> /// <param name="sex"></param> /// <param name="age"></param> public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } /// <summary> /// 設置工作經歷 /// </summary> /// <param name="workDate"></param> /// <param name="company"></param> public void SetWorkExperience(string workDate, string company) { work.WorkDate = workDate; work.Company = company; } /// <summary> /// 顯示 /// </summary> public void Display() { Console.WriteLine("{0}{1}{2}", name, sex, age); Console.WriteLine("工作經歷:{0}{1}", work.WorkDate, work.Company); } public object Clone() { //創建當前object的淺表副本 return (object)this.MemberwiseClone(); } }
客戶端調用
static void Main(string[] args) { Resume a = new Resume("張三"); a.SetPersonalInfo("男", "30"); a.SetWorkExperience("2010-2018", "騰訊公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("2010-2015", "阿里公司"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("女", "18"); c.SetWorkExperience("2010-2015", "百度公司"); a.Display(); b.Display(); c.Display(); Console.Read(); }
結果
張三 男 30
工作經歷 2010-2018 騰訊公司
張三 男 30
工作經歷 2010-2018 騰訊公司
張三 女 18
工作經歷 2010-2018 騰訊公司
被復制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用都仍然指向原來的對象,這就是淺復制。但是我們可能需要這樣一種需求,要把復制的對象所引用的對象都復制一遍。比如剛才的例子,我希望a、b、c三個引用的對象都是不同的。復制時就一變二,二變三。此時,我們就要用的方式叫“深復制”
深復制把引用對象的變量指向復制過的新對象,而不是原來被引用的對象
/// <summary> /// 工作經歷類 /// </summary> public class WorkExperience:ICloneable { private string _workDate; public string WorkDate { get { return _workDate; } set { _workDate = value; } } private string _company; public string Company { get { return _company; } set { _company = value; } } public object Clone() { //創建當前object的淺表副本 return (object)this.MemberwiseClone(); } }
/// <summary> /// 簡歷類 /// </summary> class Resume : ICloneable { private string name; private string sex; private string age; private WorkExperience work; public Resume(string name) { this.name = name; work = new WorkExperience(); } private Resume(WorkExperience work) { //提供Clone方法調用的私有構造函數,以便克隆“工作經歷”數據 this.work = (WorkExperience)work.Clone(); } /// <summary> /// 設置個人信息 /// </summary> /// <param name="sex"></param> /// <param name="age"></param> public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } /// <summary> /// 設置工作經歷 /// </summary> /// <param name="workDate"></param> /// <param name="company"></param> public void SetWorkExperience(string workDate, string company) { work.WorkDate = workDate; work.Company = company; } /// <summary> /// 顯示 /// </summary> public void Display() { Console.WriteLine("{0}{1}{2}", name, sex, age); Console.WriteLine("工作經歷:{0}{1}", work.WorkDate, work.Company); } public object Clone() { //調用私有的構造方法,讓“工作經歷”克隆完成,然后再給這個簡歷對象的相關字段賦值, //最終返回一個深復制的簡歷對象 Resume obj = new Resume(this.work); obj.name = this.name; obj.sex = this.sex; obj.age = this.age; return obj; } }
客戶端調用代碼一樣
結果
張三 男 30
工作經歷 2010-2018 騰訊公司
張三 男 30
工作經歷 2010-2015 阿里公司
張三 女 18
工作經歷 2010-2015 百度公司
由于在一些特定場合,會經常涉及深復制和淺復制,比如說,數據集對象DataSet,它就有Clone()方法和Copy()方法,Clone()方法用來復制DataSet的結構,但不復制DataSet的數據,實現了原型模式的淺復制,
Copy()方法不但復制結構,還復制數據,其實就是實現了原型模式的深復制。
到此,相信大家對“怎么理解Java設計模式的原型模式”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。