解释:从一个对象创建另外一个可定制的对象,无需知道任何创建的细节
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace StrategyMo.Prototype { public abstract class Prototype { 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(); } } }
MemberwiseClone()
客户端使用:
当然在C#中,System空间下有个ICloneable接口,继承它就有Clone方法了。
继承接口就可以实现原型模式了。
新建一个类,继承ICloneable类
public class Prototype2:ICloneable { private string id; public Prototype2(string _id) { this.id = _id; } public string Id { get { return id; } set { id = value; } } public object Clone() { return (object)this.MemberwiseClone(); } }
客户端使用,效果一样的。
深复制和浅复制
string是引用类型,值类型的特性。
MemberwiseClone,如果值类型,就逐位复制,引用类型,就拷贝引用。 这种刚就是浅复制。
比如有个类,类是引用类型的。被复制的类中含有个类,这个类拷贝的是引用。
如果想完整拷贝出来一份,修改值,不影响原来的对象,就需要深复制
下面修改下代码
public class Prototype3 : ICloneable { private string id; public SubPrototype3 sub; public Prototype3(string _id) { this.id = _id; } public Prototype3(SubPrototype3 _sub) { sub = _sub.Clone() as SubPrototype3; } public string Id { get { return id; } set { id = value; } } public object Clone() { Prototype3 pt = new Prototype3(this.sub); pt.id = this.Id; return pt; } } public class SubPrototype3 : ICloneable { private string id; public SubPrototype3(string _id) { this.id = _id; } public string Id { get { return id; } set { id = value; } } public object Clone() { return (object)this.MemberwiseClone(); } }
使用方式:
Console.WriteLine("============深复制======"); Prototype3 p3 = new Prototype3("333"); p3.sub = new SubPrototype3("ay哈哈"); Prototype3 p4 = p3.Clone() as Prototype3; Console.WriteLine("克隆的id:" + p3.Id+"---子类的id:"+p3.Id); p4.Id = "44444"; p4.sub.Id = "ay啊呀呦"; Console.WriteLine("克隆的id:" + p4.Id + ";原本的id:" + p3.Id); Console.WriteLine("克隆的子id:" + p4.sub.Id + ";原本的子id:" + p3.sub.Id);
效果:
这样客户端使用,就可以把SubPrototype3拷贝过来了。每次都是第二份的,而不是引用了。