定義與特點
原型(Prototype)模式的定義如下:用一個已經創建的實例作為原型,通過復制該原型對象來創建一個和原型相同或相似的新對象。
在這里,原型實例指定了要創建的對象的種類。用這種方式創建對象非常高效,根本無須知道對象創建的細節。
例如,Windows 操作系統的安裝通常較耗時,如果復制就快了很多。在生活中復制的例子非常多,這里不一一列舉了。
結構與實現
由於 C# 提供了 ICloneable 接口,用 C# 實現原型模式很簡單。
模式的結構
原型模式包含以下主要角色:
- 原型(Prototype):聲明一個克隆自身的接口,該角色一般有抽象類(Prototype)、接口(ICloneable)兩種實現方式(GOF使用的是抽象類,在C#中個人推薦使用接口)。
- 具體原型類(ConcretePrototype):實現原型(抽象類或接口)的 Clone() 方法,它是可被復制的對象。
- 訪問類(Client):使用具體原型類中的 Clone() 方法來復制新的對象。
使用接口作為Prototype時,其結構圖如圖所示(后面全部是接口方式的原型模式實現):
使用抽象類作為Prototype時,其結構圖如圖所示(來自GOF):
模式的實現
C# 中已經定義了 ICloneable 接口,具體原型類只要實現 ICloneable 接口就可實現對象的克隆(Object有 MemberwiseClone() 方法默認淺克隆),克隆是淺克隆還是深克隆取決於具體原型類 Clone() 的實現。其代碼如下:
//原型接口:該接口不需要自己定義,C#中已經定義好了
public interface ICloneable
{
Object Clone();
}
//抽象原型類
public abstract class Prototype
{
public abstract Object Clone();
}
//具體原型類(接口方式)
public class ConcretePrototype : /*Prototype,*/ICloneable
{
private int id;
public int Id
{
get { return id; }
}
public ConcretePrototype(int id)
{
this.id = id;
}
public Object Clone()
{
return new ConcretePrototype(id);
}
//使用抽象原型類
//public override Object Clone()
//{
// //Object的默認克隆方式(淺克隆)
// return (Prototype)this.MemberwiseClone();
//}
}
//訪問類,這里直接用的控制台的Program類
class Program
{
static void Main(string[] args)
{
ConcretePrototype cp1 = new ConcretePrototype(1);
ConcretePrototype cp2 = (ConcretePrototype)cp1.Clone();
Console.WriteLine("cp1的Id為:{0}",cp1.Id);
Console.WriteLine("cp2的Id為:{0}", cp2.Id);
Console.ReadKey();
}
}
運行結果:
cp1的Id為:1
cp2的Id為:1
應用場景
原型模式通常適用於以下場景:
- 對象之間相同或相似,即只是個別的幾個屬性不同的時候。
- 對象的創建過程比較麻煩,但復制比較簡單的時候。
擴展:帶原型管理器的原型模式
原型模式可擴展為帶原型管理器的原型模式,它在原型模式的基礎上增加了一個原型管理器 PrototypeManager 類。該類用 Dictionary(或HashMap) 保存多個復制的原型,Client 類可以通過管理器的 Get(String id) 方法從中獲取復制的原型。其結構如圖所示: