一 、 原型 (Prototype ) 模式
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出
更多的同类型对象。
从孙大圣的手段谈起
孙悟空在与黄风怪的战斗中,"使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声'变',变
有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。"换而言之,孙悟空可以根据自己的形象,
复制出很多"身外身"来。
老孙这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。
C# 对原型模式的支持
在 C#里面,我们可以很容易的通过 Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现 C#中的
ICloneable 接口。ICloneable 接口中有一 Clone 方法,可以在类中复写实现自定义的克隆方法。克隆的实现
方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
(以下摘自:《.NET 框架程序设计(修订版)》,李建忠译)浅拷贝是指当对象的字段值被拷贝时,字段引用
的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两
个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对
象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符
串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变
一个对象对另外一个对象没有任何影响。
二 、 Prototype 模式的结构
客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个 C#接口或抽象类实现。此角色给出所有的具体
原型类所需的接口。在 C#中,抽象原型角色通常实现了 ICloneable 接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。
三 、 程序举例 :
下面的程序给出了一个示意性的实现:
[C#] 纯文本查看 复制代码 // Prototype pattern -- Structural example
using System;
// "Prototype"
abstract class Prototype
{
// Fields
private string id;
// Constructors
public Prototype( string id )
{
this.id = id;
}
public string Id
{
get{ return id; }
}
// Methods
abstract public Prototype Clone();
}
// "ConcretePrototype1"
class ConcretePrototype1 : Prototype
{
// Constructors
public ConcretePrototype1( string id ) : base ( id ) {}
// Methods
override public Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
// "ConcretePrototype2"
class ConcretePrototype2 : Prototype
{
// Constructors
public ConcretePrototype2( string id ) : base ( id ) {}
// Methods
override public Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
/// <summary>
/// Client test
/// </summary>
class Client
{
public static void Main( string[] args )
{
// 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 );
}
}
这个例子实现了一个浅拷贝。其中 MemberwiseClone()方法是 Object 类的一个受保护方法,实现了对象的浅
拷贝。如果希望实现一个深拷贝,应该实现 ICloneable 接口,并自己编写 ICloneable 的 Clone 接口方法。
|