C語言編程中使用設計模式中的原型模式的講解
一、引言
在軟件系統中,當創建一個類的實例的過程很昂貴或很複雜,並且我們需要創建多個這樣類的實例時,如果我們用new操作符去創建這樣的類實例,這未免會增加創建類的複雜度和耗費更多的內存空間,因爲這樣在內存中分配了多個一樣的類實例對象,然後如果採用工廠模式來創建這樣的系統的話,隨着產品類的不斷增加,導致子類的數量不斷增多,反而增加了系統複雜程度,所以在這裏使用工廠模式來封裝類創建過程並不合適,然而原型模式可以很好地解決這個問題,因爲每個類實例都是相同的,當我們需要多個相同的類實例時,沒必要每次都使用new運算符去創建相同的'類實例對象,此時我們一般思路就是想——只創建一個類實例對象,如果後面需要更多這樣的實例,可以通過對原來對象拷貝一份來完成創建,這樣在內存中不需要創建多個相同的類實例,從而減少內存的消耗和達到類實例的複用。 然而這個思路正是原型模式的實現方式。下面就具體介紹下設計模式中的原型設計模式。
二、原型模式的詳細介紹
我們來看一個入學考試場景實例
基對象(一般爲接口,抽象類):考試題(樣卷)
原型模式的復職克隆:根據需要印刷考卷,這裏的考卷都是複製考試題樣卷
客戶端:學生答卷,同一套試卷,學生做題不可能一模一樣
類圖:
接口:試卷樣例代碼
///
/// 選答題 ///
public class SelectTest { private string other; public string 你老婆多大 { get { return r; } set { r = value; } } } ///
/// 面試題 ///
public interface Itest { Itest Clone(); string 知道設計模式嗎 { get; set; } string 設計模式有幾種 { get; set; } string 你知道那些 { get; set; } SelectTest 附加題 { get; set; } Test Test { get; set; } Test Test1 { get; set; } }
複製克隆:複印機
///
/// 繼承Itest接口 ///
public class Test : Itest { private string one; private string two; private string three; private SelectTest other=new SelectTest(); public string 知道設計模式嗎 { get { return ; } set { = value; } } public string 設計模式有幾種 { get { return ; } set { = value; } } public string 你知道那些 { get { return e; } set { e = value; } } public SelectTest 附加題 { get { return r; } set { r = value; } } #region IColorDemo 成員 public Itest Clone() { //克隆當前類 return (Itest)erwiseClone(); } #endregion }
客戶端,髮捲做題
static void Main() { //印刷試卷 Itest test = new Test(); //複製樣本試卷 Itest test1 = e(); //考生1 test.設計模式有幾種 = "23"; test.附加題.你老婆多大 = "18"; //考生2 test1.設計模式有幾種 = "24"; test1.附加題.你老婆多大 = "20"; //顯示考生答卷內容 eLine("test設計模式有幾種:" + test.設計模式有幾種); //23 eLine("test附加題.你老婆多大:" + test.附加題.你老婆多大); //20 eLine("test1設計模式有幾種:" + test1.設計模式有幾種); //24 eLine("test1附加題.你老婆多大:" + test1.附加題.你老婆多大); //20 Key(); }
注意:這裏兩個人答得不一樣,爲什麼附加題中,老婆年齡都爲20?
這裏涉及到深拷貝,淺拷貝問題,值類型是放在棧上的,拷貝之後,會自會在站上重新add一個,而class屬於引用類型,拷貝之後,棧上重新分配啦一個指針,可指針卻指向同一個位置的資源。淺拷貝,只拷貝值類型,深拷貝,引用類型也拷貝複製。
解決方案:
public Itest Clone() { //克隆當前類 Itest itst= (Itest)erwiseClone(); SelectTest st = new SelectTest(); st.你老婆多大 = r.你老婆多大; itst.附加題 = st; return itst; }
使用序列化解決
///
/// 選答題 ///
[Serializable] public class SelectTest { private string other; public string 你老婆多大 { get { return r; } set { r = value; } } } ///
/// 面試題 ///
public interface Itest { Itest Clone(); string 知道設計模式嗎 { get; set; } string 設計模式有幾種 { get; set; } string 你知道那些 { get; set; } SelectTest 附加題 { get; set; } } ///
/// 繼承Itest接口 ///
public class Test : Itest { private string one; private string two; private string three; private SelectTest other=new SelectTest(); public string 知道設計模式嗎 { get { return ; } set { = value; } } public string 設計模式有幾種 { get { return ; } set { = value; } } public string 你知道那些 { get { return e; } set { e = value; } } public SelectTest 附加題 { get { return r; } set { r = value; } } public Itest Clone() { SerializableHelper SerializableHelper = new 原型模式alizableHelper(); string target = alizable(this); return alizable
(target); } } public class SerializableHelper { public string Serializable(object target) { using (MemoryStream stream = new MemoryStream()) { new BinaryFormatter()alize(stream, target); return se64String(ray()); } } public object Derializable(string target) { byte[] targetArray = Base64String(target); using (MemoryStream stream = new MemoryStream(targetArray)) { return new BinaryFormatter()rialize(stream); } } public T Derializable(string target) { return (T)Derializable(target); } }
這就是對原型模式的運用。介紹完原型模式的實現代碼之後,下面看下原型模式的類圖,通過類圖來理清原型模式實現中類之間的關係。具體類圖如下:
三、原型模式的優缺點
原型模式的優點有:
原型模式向客戶隱藏了創建新實例的複雜性
原型模式允許動態增加或較少產品類。
原型模式簡化了實例的創建結構,工廠方法模式需要有一個與產品類等級結構相同的等級結構,而原型模式不需要這樣。
產品類不需要事先確定產品的等級結構,因爲原型模式適用於任何的等級結構
原型模式的缺點有:
每個類必須配備一個克隆方法
配備克隆方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支持串行化的間接對象,或者引用含有循環結構的時候。
四、中原型模式的實現
在中可以很容易地通過實現ICloneable接口(這個接口就是原型,提供克隆方法,相當於與上面代碼中MonkeyKingPrototype抽象類)中Clone()方法來實現原型模式,如果我們想我們自定義的類具有克隆的功能,首先定義類繼承與ICloneable接口並實現Clone方法。在中實現了原型模式的類如下圖所示(圖中只截取了部分,可以用Reflector反編譯工具進行查看):
相關文章
-
該怎麼使用Java設計模式編程中的OCP開閉原則?
OCP開閉原則定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。問題由來:在軟件的生命週期內,因爲變化、升級和維護等原因需要對軟件原有代碼進行修改時,可能會給舊代碼中引入錯誤,也可能會使我們不得不對整個 -
Java的設計模式編程中責任鏈模式的運用的實例講解
定義:使多個對象都有機會處理請求,從而避免了請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。類型:行爲類模式類圖:首先來看一段代碼:public void test(int i, Re -
解析Java的設計模式編程之解釋器模式的運用
0.解釋器(Interpreter)模式定義 :給定一門語言,定義它的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中句子。 屬於行爲型模式。解釋器模式在實際的系統開發中使用的非常少,因爲它會引起效率、性能以及 -
C語言函數式編程中惰性求值詳解
在開始介紹今天要講的知識之前,我們想要理解嚴格求值策略和非嚴格求值策略之間的區別,這樣我們才能夠深有體會的明白爲什麼需要利用這個技術。首先需要說明的是C#語言小部分採用了非嚴格求值策略,大部分還是嚴格求值策略 -
高中語文優秀教案教學設計課型模式
引導語:通過學習馬克思的有關論述,開闊學生的思路,引導學生對本文的觀點做進一步研討,下面是yjbys小編爲你帶來的高中語文優秀教案教學設計課型模式,希望對你有所幫助。 一、指導思想爲全面實施素質教育,深化課程改革,打 -
javascript模式設計之工廠模式學習心得
模式類型:工廠模式模式說明:常用模式之一,用來動態創建對象適用範圍:在運行期間需要在一系列可互換的子類中進行選擇的類注意事項:接口的實現,從而使不同子類可以被同等的'對待,恰當的使用工廠模式,但不要拘泥與形式,理解 -
簡單講解C語言中宏的定義與使用
在不斷地發展中,我們學校也得到了很大的發展,這是我們一直以來不斷的努力,不斷進步的最好明證。學校一直在教學成績上取得很大的進步,我們學校的名氣也逐漸的在周邊地區擴大開來。雖然學校行政後勤部門不直接參與到學校教 -
PHP中的設計模式詳解
導語:設計模式並不是一種用來解釋的模式,它們並不是像鏈表那樣的常見的數據結構,也不是某種特殊的應用或者框架設計。下面是PHP中的設計模式詳解,一起來學習下吧: 設計模式的解釋如下:descriptions of communicating objec -
淺析高中英語語法教學中講授模式的應用
【摘 要】闡述語法教學模式中講授模式的四個實施步驟:闡明目標與設置情境、呈現先行組織者、講授新知識、檢查理解程度及拓展思維,探討講授模式在高中英語語法教學中的應用。【關鍵詞】高中 英語語法教學 講授模式【中 -
國中物理教學中問題導向型教學模式的構建模型分析論文
摘 要:問題導向型教學模式是教師通過問題引發學生思考,並使學生積極融入教學主題中。國中物理教學中運用問題導向型教學模式,可以有效地促進學生從多角度、多層面進行問題探索,進而找到解決問題的方法,在問題探究中,學生的