標籤:
一、 原型(Prototype)模式
通過給出一個原型對象來指明所要建立的物件類型,然後用複製這個原型對象的辦法建立出更多的同類型對象。Prototype模式允許一個對象再建立另外一個可定製的對象,根本無需知道任何如何建立的細節。
二、原型模式的結構
三、原型模式的詳細介紹
在現實生活中,也有很多原型設計模式的例子,例如,細胞分裂的過程,一個細胞的有絲分裂產生兩個相同的細胞;還有西遊記中孫悟空變出後孫的本領和火影忍者中鳴人的隱分身忍術等。下面就以孫悟空為例子來示範下原型模式的實現。具體的實現代碼如下:
///火影忍者中鳴人的影分身和孫悟空的的變都是原型模式 class Client { static void Main(string[] args) { // 孫悟空 原型 MonkeyKingPrototype prototypeMonkeyKing = new ConcretePrototype("MonkeyKing"); // 變一個 MonkeyKingPrototype cloneMonkeyKing = prototypeMonkeyKing.Clone() as ConcretePrototype; Console.WriteLine("Cloned1:\t"+cloneMonkeyKing.Id); // 變兩個 MonkeyKingPrototype cloneMonkeyKing2 = prototypeMonkeyKing.Clone() as ConcretePrototype; Console.WriteLine("Cloned2:\t" + cloneMonkeyKing2.Id); Console.ReadLine(); } } /// <summary> /// 孫悟空原型 /// </summary> public abstract class MonkeyKingPrototype { public string Id { get; set; } public MonkeyKingPrototype(string id) { this.Id = id; } // 複製方法,即孫大聖說“變” public abstract MonkeyKingPrototype Clone(); } /// <summary> /// 建立具體原型 /// </summary> public class ConcretePrototype : MonkeyKingPrototype { public ConcretePrototype(string id) : base(id) { } /// <summary> /// 淺拷貝 /// </summary> /// <returns></returns> public override MonkeyKingPrototype Clone() { // 調用MemberwiseClone方法實現的是淺拷貝,另外還有深拷貝 return (MonkeyKingPrototype)this.MemberwiseClone(); } }
上面原型模式的運行結果為(從運行結果可以看出,建立的兩個拷貝對象的ID屬性都是與原型對象ID屬性一樣的):
上面代碼實現的淺拷貝的方式,淺拷貝是指當對象的欄位值被拷貝時,欄位引用的對象不會被拷貝。例如,如果一個對象有一個指向字串的欄位,並且我們對該對象做了一個淺拷貝,那麼這兩個對象將引用同一個字串,而深拷貝是對對象執行個體中欄位引用的對象也進行拷貝,如果一個對象有一個指向字串的欄位,並且我們對該對象進行了深拷貝的話,那麼我們將建立一個對象和一個新的字串,新的對象將引用新的字串。也就是說,執行深拷貝建立的新對象和原來對象不會共用任何東西,改變一個對象對另外一個對象沒有任何影響,而執行淺拷貝建立的新對象與原來對象共用成員,改變一個對象,另外一個對象的成員也會改變。
介紹完原型模式的實現代碼之後,下面看下原型模式的類圖,通過類圖來理清原型模式實現中類之間的關係。具體類圖如下:
四、原型模式的優缺點
原型模式的優點有:
- 原型模式向客戶隱藏了建立新執行個體的複雜性
- 原型模式允許動態增加或較少產品類。
- 原型模式簡化了執行個體的建立結構,Factory 方法模式需要有一個與產品類等級結構相同的等級結構,而原型模式不需要這樣。
- 產品類不需要事先確定產品的等級結構,因為原型模式適用於任何的等級結構
原型模式的缺點有:
- 每個類必須配備一個複製方法
- 配備複製方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支援序列化的間接對象,或者引用含有迴圈結構的時候。
五、.NET中原型模式的實現
在.NET中可以很容易地通過實現ICloneable介面(這個介面就是原型,提供複製方法,相當於與上面代碼中MonkeyKingPrototype抽象類別)中Clone()方法來實現原型模式,如果我們想我們自訂的類具有複製的功能,首先定義類繼承與ICloneable介面並實現Clone方法。在.NET中實現了原型模式的類如所示(圖中只截取了部分,可以用Reflector反編譯工具進行查看):
總結
到這裡關於原型模式的介紹就結束了,原型模式用一個原型對象來指明所要建立的物件類型,然後用複製這個原型對象的方法來建立出更多的同類型對象,它與Factory 方法模式的實現非常相似,其中原型模式中的Clone方法就類似Factory 方法模式中的Factory 方法,只是Factory 方法模式的Factory 方法是通過new運算子重新建立一個新的對象(相當於原型模式的深拷貝實現),而原型模式是通過調用MemberwiseClone方法來對原來對象進行拷貝,也就是複製,同時在原型模式優點中也介紹了與Factory 方法的區別。
原型模式(Prototype Pattern)