一、 原型(Prototype)模式
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
从孙大圣的手段谈起
孙悟空在与黄风怪的战斗中,"使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声'变',变有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。"换而言之,孙悟空可以根据自己的形象,复制出很多"身外身"来。
老孙这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。
C#对原型模式的支持
在C#里面,我们可以很容易的通过Clone()-克隆-方法实现原型模式。
二、 Prototype模式的结构:
客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。
class Program { static void Main(string[] args) { // 创建两个实例和克隆 ConcretePrototype1 p1 = new ConcretePrototype1("I"); ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone(); Console.WriteLine("Cloned: {0}", c1.Id); ConcretePrototype2 p2 = new ConcretePrototype2("II"); ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone(); Console.WriteLine("Cloned: {0}", c2.Id); Console.ReadLine(); } } //Prototype 抽象 原型 public abstract class Prototype { private string id; // 构造函数 public Prototype(string id) { this.id = id; } public string Id { get { return id; } } // 方法 public abstract Prototype Clone(); } //具体原型 1 public class ConcretePrototype1 : Prototype { // 构造函数 base(id) 实现基类构造函数 public ConcretePrototype1(string id) : base(id) { } // 方法 public override Prototype Clone() { // 浅拷贝 return (Prototype)this.MemberwiseClone(); } } // 具体原型 2 public class ConcretePrototype2 : Prototype { // 构造函数 public ConcretePrototype2(string id) : base(id) { } // 方法 public override Prototype Clone() { // 浅拷贝 return (Prototype)this.MemberwiseClone(); } }
三、 带Prototype Manager的原型模式
客户(Client)角色:客户端类向原型管理器提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
class Program { static void Main(string[] args) { ColorManager colormanager = new ColorManager(); // 初始化与标准颜色 colormanager["red"] = new Color(255, 0, 0); colormanager["green"] = new Color(0, 255, 0); colormanager["blue"] = new Color(0, 0, 255); // 用户添加个性化的颜色 colormanager["angry"] = new Color(255, 54, 0); colormanager["peace"] = new Color(128, 211, 128); colormanager["flame"] = new Color(211, 34, 20); // 用户使用所选的颜色 string colorName = "red"; Color color1 = (Color)colormanager[colorName].Clone(); color1.Display(); colorName = "peace"; Color color2 = (Color)colormanager[colorName].Clone(); color2.Display(); colorName = "flame"; Color color3 = (Color)colormanager[colorName].Clone(); color3.Display(); Console.ReadLine(); } } /// <summary> /// 原型管理器 ColorManager /// </summary> public class ColorManager { Hashtable colors = new Hashtable(); // 索引器 public ColorPrototype this[string name] { get { return (ColorPrototype)colors[name]; } set { colors.Add(name, value); } } } /// <summary> /// 颜色 抽象原型 --> ColorPrototype /// </summary> public abstract class ColorPrototype { //方法 public abstract ColorPrototype Clone(); } /// <summary> /// 具体原型 Color /// </summary> public class Color : ColorPrototype { private int red; private int green; private int blue; //构造函数 public Color(int red, int green, int blue) { this.red = red; this.green = green; this.blue = blue; } //重写基类方法 public override ColorPrototype Clone() { return (ColorPrototype)this.MemberwiseClone(); } public void Display() { Console.WriteLine("RGB values are: {0},{1},{2}", red, green, blue); } }