引言:
原型,感觉就是拷贝,只是给拷贝分了深拷贝和浅拷贝。
理解:
在C#.Net里面,我们可以很容易的通过Clone()方法实现原型模式。
任何类,只要想支持克隆,必须实现C#中的ICloneable接口。
ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。
克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
说明:浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式。
UML图:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html)
示例代码:
public interface IObjectOne { IObjectOne Clone(); void Write(); } // Object public class Object1 : IObjectOne { public String _val = "A"; public User _user = new User(); public IObjectOne Clone() { _user.Name = "A name"; return (IObjectOne)this.MemberwiseClone(); } public void Write() { Console.WriteLine(_user.Name); Console.WriteLine("Object " + _val); } } // 实体 public class User { public String Name { get; set; } }
调用
static void Main(string[] args) { Object1 obj = new Object1(); Object1 objCopy = (Object1)obj.Clone(); // 值类型 objCopy._val = "AA"; // 引用类型 objCopy._user.Name = "AA name"; objCopy.Write(); obj.Write(); Console.ReadKey(); }
结果
从结果我们看出,MemberwiseClone方法是浅拷贝,因为只有值类型的被拷贝了,引用类型的没有被拷贝。
理解拷贝:
public interface IObjectTwo { // 浅拷贝 IObjectTwo Clone(); // 深拷贝 IObjectTwo DeepClone(String name); // 输出 void Write(); } public class Object3 : IObjectTwo { public String _val = "A"; public User _user = new User(); public Object3() { _user.Name = "A name"; } // 浅拷贝 public IObjectTwo Clone() { return (IObjectTwo)this.MemberwiseClone(); } // 深拷贝 public IObjectTwo DeepClone(String name) { Object3 nowObj = new Object3(); User obj = new User(); obj.Name = name; nowObj._val = this._val; nowObj._user = obj; return (IObjectTwo)nowObj; } // 输出 public void Write() { Console.WriteLine(_user.Name); Console.WriteLine("Object " + _val); } }
static void Main(string[] args) { Object1 obj = new Object1(); Object1 objCopy = (Object1)obj.Clone(); // 值类型 objCopy._val = "AA"; // 引用类型 objCopy._user.Name = "AA name"; objCopy.Write(); obj.Write(); Console.WriteLine(); Console.WriteLine("--------------------"); Console.WriteLine(); Object3 nowObj = new Object3(); Object3 objCopy2 = (Object3)nowObj.Clone(); objCopy2._val = "XX"; objCopy2._user.Name = "XX name"; objCopy2.Write(); // 深拷贝 Object3 objCopy3 = (Object3)nowObj.DeepClone("My Name"); objCopy3._val = "YY"; objCopy3.Write(); objCopy3._user.Name = "Test"; objCopy3.Write(); nowObj.Write(); Console.ReadKey(); } }
结果:
从结果知道,拷贝一个引用类型,一定是New这个对象。这个其实跟堆栈有关,当new一个对象时,会在堆上面新分配一个区域,用于新对象的存储。
但是给一个引用对象赋值另一个引用对象时,是把引用的指针给了对象,并没有重新分配存储区域,所以修改这个对象就会影响,整个上下文中的这个对象,
因为,修改的是一个存储区域。
总结:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html)
1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。
应用场景:
如:一个方法,里面的参数是一个实体类,ProcessMessage(User userInfo),而调用这个方法的方法是ReturnProcess()
public void ReturnProcess(){
User userInfo = new User();
// 调用前
......
ProcessMessage(userInfo);
//调用后
......
}
那么,在ProcessMessage修改对象uerInfo,会直接影响到 调用后,userInfo的值。
所以在一些设计中需要考虑子方法中修改对象带来的影响,
所以我们需要深拷贝和浅拷贝。
也就是我们说的原型模式。
代码下载:
百度网盘 http://pan.baidu.com/s/1c0iSVlu