今天刚看了原型模式,刚一开始还真没弄明白这个模式想干嘛,因为一直都在使用clone方法,我觉得到处深度clone和到处new一个对象的实例,那不是一样的吗?后来查了资料也发帖子问了,其实clone和new有区别的,很简单,clone后的对象的实例不仅和原对象的实例结构一致而且值也一致;而new出来的对象的实例只是结构一致,值是默认值。其实原型模式它的根本目的是创建对象的实例,而且是要创建和已经存在的那个实例一模一样,包括状态。这样的话clone就显示出优势了。那先看看什么是原型模式吧。
1、 概念
用原型的实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2、 模型
它的模型是一个原型类实现一个接口或继承抽象类(这个接口和类一定要包含clone方法),并重写clone方法。
//抽象父类,包含一个clone方法:
public abstract class AbstractProtoType
{
private string id;
public AbstractProtoType(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
public abstract AbstractProtoType Clone();
}
//原型类,继承了抽象类,并实现了clone方法:
public class ProtoTypeClass : AbstractProtoType
{
public ProtoTypeClass(string id)
: base(id)
{
}
public override AbstractProtoType Clone()
{
return (AbstractProtoType)this.MemberwiseClone();
}
}
调用:
using System;
using System.Collections.Generic;
using System.Text;
namespace PrototypePattern
{
class Program
{
static void Main(string[] args)
{
ProtoTypeClass real = new ProtoTypeClass("2011");
Console.WriteLine("原型的id:{0}", real.Id);
ProtoTypeClass copy =(ProtoTypeClass)real.Clone();
Console.WriteLine("复制的id:{0}", copy.Id);
Console.ReadKey();
}
}
}
结果:
3、 c#.NET中的使用
(1)、浅度复制
在.NET中原型类实现Icloneable就可以了。
代码:
public class ProtoTypeClass : ICloneable
{
private string id;
public ProtoTypeClass(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
public object Clone()
{
return (ProtoTypeClass)this.MemberwiseClone();
}
}
调用:
static void Main(string[] args)
{
ProtoTypeClass real = new ProtoTypeClass("2011");
Console.WriteLine("原型的id:{0}", real.Id);
ProtoTypeClass copy = (ProtoTypeClass)real.Clone();
Console.WriteLine("复制的id:{0}", copy.Id);
Console.ReadKey();
}
结果:
如果原型类中对其他对象的引用的话,这种复制只能复制这个引用,因此复制后的实例中的该对象引用和原型中的对象指向同一个引用。这种复制成为浅度复制。
(2)深度复制
如果原型类中包含其它对象的引用,则深度复制情形如下:
public class OtherClass:ICloneable
{
private string id;
private string name;
public OtherClass(string idStr, string nameStr)
{
id = idStr;
name = nameStr;
}
public string Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public object Clone()
{
return (OtherClass)this.MemberwiseClone();
}
}
public class ProtoTypeClass : ICloneable
{
private string id;
private OtherClass oclass;
public ProtoTypeClass(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
public OtherClass Oclass
{
get { return oclass; }
set { oclass = value; }
}
public object Clone()
{
object obj = (ProtoTypeClass)this.MemberwiseClone();
if (oclass != null)
oclass = (OtherClass)oclass.Clone();
return obj;
}
}
调用:
static void Main(string[] args)
{
ProtoTypeClass real = new ProtoTypeClass("2011");
real.Oclass = new OtherClass("2012", "兰戈");
Console.WriteLine("原型的id:{0},原型引用类的id:{1},原型引用类的name:{2}",
real.Id,real.Oclass.Id,real.Oclass.Name);
ProtoTypeClass copy = (ProtoTypeClass)real.Clone();
Console.WriteLine("复制的id:{0},复制引用类的id:{1},复制引用类的name:{2}",
copy.Id, copy.Oclass.Id, copy.Oclass.Name);
Console.ReadKey();
}
结果:
深度复制将原型里包含的对象指向的类也复制过来。这样copy和real就是完全相同的对象,但是是独立的,销毁real,copy依然存在,并且值保持不变的。
有一点要注意原型模式不是主要是clone,clone只是达到原型模式的一种方法。原型模式的意义是,原型的变化要使得使用原形的地方同时要变化,但不用修改代码。