原型模式
原型模式概念:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
原型模式的本质:克隆生成对象。
原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是由对象的内部提供克隆的方法。
原型模式会要求对象实现一个可以克隆自身的接口,这样就可以通过拷贝一个实例对象本身来创建一个新实例。如果把这个方法定义在接口上,看起来就像是通过接口来创建了新的接口对象。这样一来,就不需要关心这个实例本身的类型,只要它实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无需再去new来创建。
以下两种情况都可以考虑使用原型模式:
1.如果说我们的对象类型不是刚开始就能确定,而是这个类型是在运行期确定的话,那么我们通过这个类型的对象克隆出一个新的类型更容易。
2.有的时候我们可能在实际的项目中需要一个对象在某个状态下的副本。
3.当我们在处理一些对象比较简单,并且对象之间的区别很小,可能只是很固定的几个属性不同的时候,可能我们使用原型模式更合适。
原型模式的结构图如下:
public interface Prototype { Prototype clone(); } public class ConcretePrototypeOne:Prototype { public Prototype clone() { return (Prototype)this.MemberwiseClone(); } } static void Main(string[] args) { Prototype prototype =new ConcretePrototypeOne(); Prototype clonePrototype = prototype.clone(); }
注意MemberwiseClone()方法只是浅拷贝,如果ConcretePrototypeOne的成员全是值类型还好,但如果有引用类型就不行了,就需要深拷贝了,比如说ConcretePrototypeOne有一个引用类型的成员Home:
public class ConcretePrototypeOne:Prototype { public Home home; public Prototype clone() { Prototype prototype = (Prototype)this.MemberwiseClone(); prototype.home = home.clone(); return prototype; } } public class Home:ICloneable { public Object clone() { return (Home)this.MemberwiseClone(); } } static void Main(string[] args) { Prototype prototype =new ConcretePrototypeOne(); prototype.home = new Home(); Prototype clonePrototype = prototype.clone(); }
可以看出我们需要让Home也实现一个clone方法,如果Home里也有引用类型的成员,那么这个成员也需要实现clone方法,以此递归。
ICloneable是.NET中提供的一个接口,其中只有一个唯一的Clone方法。
其实可以通过序列化/反序列化的方法来实现深拷贝,具体可参考http://www.cnblogs.com/hegezhou_hot/archive/2010/12/04/1896471.html