用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
1、基本原型模式
原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
public abstract class Prototype
{
//属性
private string id;
//构造方法
public Prototype(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
//克隆自身的接口
public abstract Prototype Clone();
}
{
//属性
private string id;
//构造方法
public Prototype(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
//克隆自身的接口
public abstract Prototype Clone();
}
public class ConcretePrototype1:Prototype
{
//实现克隆自身操作
public ConcretePrototype1(string id)
: base(id)
{
}
public override Prototype Clone()
{
//创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。
//如果字段是指类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;
//因此,原始对象及其副本引用同一对象
return (Prototype)this.MemberwiseClone();
}
}
{
//实现克隆自身操作
public ConcretePrototype1(string id)
: base(id)
{
}
public override Prototype Clone()
{
//创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。
//如果字段是指类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;
//因此,原始对象及其副本引用同一对象
return (Prototype)this.MemberwiseClone();
}
}
static void Main(string[] args)
{
ConcretePrototype1 p1 = new ConcretePrototype1("I");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Cloned:{0}", c1.Id);
Console.Read();
}
{
ConcretePrototype1 p1 = new ConcretePrototype1("I");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Cloned:{0}", c1.Id);
Console.Read();
}
返回结果为Cloned:I,表明c1把p1的对象拷贝过来了。
但在.net中,不需要建prototype类,因为System命名空间中提供了ICloneable接口,其中的方法clone()可以直接完成基本原型模式。
2、深复制
上面讲述的是浅复制,因为MemberwiseClone在复制引用时只复制了地址,没有复制值。如果对这个对象进行修改,则会影响被复制的类。
浅复制指被复制到所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
深复制只需要对引用对象的值再使用一次浅复制,保证复制引用对象时,引用对象的值也复制到新对象,就可以了。
在.net中,Copy()方法所完成的就是深复制,和Clone()的浅复制对应。
3、适用范围
这个模式一般在初始化的信息不发生大的变化的情况下使用,既隐藏了细节,又不用初始化信息,提高了性能。