今天刚看了原型模式,刚一开始还真没弄明白这个模式想干嘛,因为一直都在使用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只是达到原型模式的一种方法。原型模式的意义是,原型的变化要使得使用原形的地方同时要变化,但不用修改代码。