一 概念
原型模式(Prototype Pattern)是一种对象创建型模式,用原型模式可以用原型实例指定创建对象的种类,它允许通过一个原型对象创建多个同类型的其他对象,而无需知道该对象的创建细节。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。(浅克隆)
浅克隆:如果原型对象的成员变量是值类型(如int、double、byte、boolean等),将复制一份给克隆对象;如果原型对象的成员变量是引用类型(如类、接口、数组等复杂数据结构),则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
深克隆: 在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
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);
// Wait for user
Console.Read();
}
}
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();
}
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id)
: base(id)
{
}
public override Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
class ConcretePrototype2 : Prototype
{
// Constructor
public ConcretePrototype2(string id)
: base(id)
{
}
public override Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
二 优点: 1、性能提高。 2、逃避构造函数的约束。
三 缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。