一、?原型(Prototype)模式
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
从孙大圣的手段谈起
孙悟空在与黄风怪的战斗中,"使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声'变',变有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。"换而言之,孙悟空可以根据自己的形象,复制出很多"身外身"来。
老孙这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。
C#对原型模式的支持
在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
(以下摘自:《.NET框架程序设计(修订版)》,李建忠译)浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。
二、?Prototype模式的结构:
? 
客户(Client)角色:客户类提出创建对象的请求。 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。
using System;
namespace DoFactory.GangOfFour.Prototype.Structural { ? ? // MainApp test application
? class MainApp ? { ??? ??? static void Main() ??? { ????? // Create two instances and clone each
????? 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);
????? // Wait for user ????? Console.Read(); ??? } ? }
? // "Prototype"
? abstract class Prototype ? { ??? private string id;
??? // Constructor ??? public Prototype(string id) ??? { ????? this.id = id; ??? }
??? // Property ??? public string Id ??? { ????? get{ return id; } ??? }
??? public abstract Prototype Clone(); ? }
? // "ConcretePrototype1"
? class ConcretePrototype1 : Prototype ? { ??? // Constructor ??? public ConcretePrototype1(string id) : base(id) ??? { ??? }
??? public override Prototype Clone() ??? { ????? // Shallow copy ????? return (Prototype)this.MemberwiseClone(); ??? } ? }
? // "ConcretePrototype2"
? class ConcretePrototype2 : Prototype ? { ??? // Constructor ??? public ConcretePrototype2(string id) : base(id) ??? { ??? }
??? public override Prototype Clone() ??? { ????? // Shallow copy ????? return (Prototype)this.MemberwiseClone(); ??? } ? } } 四、?带Prototype Manager的原型模式
原型模式的第二种形式是带原型管理器的原型模式,其UML图如下:
? 
客户(Client)角色:客户端类向原型管理器提出创建对象的请求。 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。 原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
下面这个例子演示了在原型管理器中存储用户预先定义的颜色原型,客户通过原型管理器克隆颜色对象。
六、?Prototype模式的优点与缺点
Prototype模式的优点包括
1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。
Prototype模式的缺点:
Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|