技术开发 频道

创建型模式篇-原型模式(Prototype Pattern)


    可以看到,客户程序通过注册原型实例就可以将一个具体产品类并入到系统中,在运行时刻,可以动态的建立和删除原型。最后还要注意一点,在上面的例子中,用的是浅表复制。如果想做深复制,需要通过序列化的方式来实现。经过了上面的分析之后,我们再来思考下面的问题:

1.为什么需要Prototype模式?

    引入原型模式的本质在于利用已有的一个原型对象,快速的生成和原型对象一样的实例。你有一个A的实例a:A a = new A();现在你想生成和car1一样的一个实例b,按照原型模式,应该是这样:A b = a.Clone();而不是重新再new一个A对象。通过上面这句话就可以得到一个和a一样的实例,确切的说,应该是它们的数据成员是一样的。Prototype模式同样是返回了一个A对象而没有使用new操作。

2.引入Prototype模式带来了什么好处?

    可以看到,引入Prototype模式后我们不再需要一个与具体产品等级结构平行的工厂方法类,减少了类的构造,同时客户程序可以在运行时刻建立和删除原型。

3.Prototype模式满足了哪些面向对象的设计原则?

    依赖倒置原则:上面的例子,原型管理器(ColorManager)仅仅依赖于抽象部分(ColorPrototype),而具体实现细节(ConcteteColorPrototype)则依赖与抽象部分(ColorPrototype),所以Prototype很好的满足了依赖倒置原则。



通过序列化实现深拷贝

    要实现深拷贝,可以通过序列化的方式。抽象类及具体类都必须标注为可序列化的[Serializable],上面的例子加上深拷贝之后的完整程序如下:
using System; using System.Collections; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; [Serializable] abstract class ColorPrototype { public abstract ColorPrototype Clone(bool Deep); } [Serializable] class ConcteteColorPrototype : ColorPrototype { private int _red, _green, _blue; public ConcteteColorPrototype(int red, int green, int blue) { this._red = red; this._green = green; this._blue = blue; } public override ColorPrototype Clone(bool Deep) { if(Deep) return CreateDeepCopy(); else return (ColorPrototype) this.MemberwiseClone(); } //实现深拷贝 public ColorPrototype CreateDeepCopy() { ColorPrototype colorPrototype; MemoryStream memoryStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, this); memoryStream.Position = 0; colorPrototype = (ColorPrototype)formatter.Deserialize(memoryStream); return colorPrototype; } public ConcteteColorPrototype Create(int red,int green,int blue) { return new ConcteteColorPrototype(red,green,blue); } public void Display(string _colorname) { Console.WriteLine("{0}'s RGB Values are: {1},{2},{3}", _colorname,_red, _green, _blue ); } } class ColorManager { Hashtable colors = new Hashtable(); public ColorPrototype this[string name] { get { return (ColorPrototype)colors[name]; } set { colors.Add(name,value); } } } class App { public static void Main(string[] args) { ColorManager colormanager = new ColorManager(); //初始化颜色 colormanager["red"] = new ConcteteColorPrototype(255, 0, 0); colormanager["green"] = new ConcteteColorPrototype(0, 255, 0); colormanager["blue"] = new ConcteteColorPrototype(0, 0, 255); colormanager["angry"] = new ConcteteColorPrototype(255, 54, 0); colormanager["peace"] = new ConcteteColorPrototype(128, 211, 128); colormanager["flame"] = new ConcteteColorPrototype(211, 34, 20); //使用颜色 string colorName = "red"; ConcteteColorPrototype c1 = (ConcteteColorPrototype)colormanager[colorName].Clone(false); c1.Display(colorName); colorName = "peace"; ConcteteColorPrototype c2 = (ConcteteColorPrototype)colormanager[colorName].Clone(true); c2.Display(colorName); colorName = "flame"; ConcteteColorPrototype c3 = (ConcteteColorPrototype)colormanager[colorName].Clone(true); c3.Display(colorName); Console.ReadLine(); } }
0
相关文章