C# 原型模式
原型模式是一种创建型的设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建立实例,被复制的实例就是我们所称的原型,这个原型是可以定制的。
一般来说,我们创建对象,可能用单列模式比较多点,对于不是很复杂的对象,用单列模式是没有啥问题的,但是如果你要创建一个很复杂的或者耗时的实例,复制一个已经存在的实例可以使得程序运行更加高效,或者创建值相等,名称不一样得数据。
原型模式也可以简单理解为:深拷贝和浅拷贝。
浅拷贝:将对象中所有得字段复制到新得对象(副本)中,其中,值类型的字段的值被复制到副本中后,在副本中修改不会影响到源对象的值,而引用类型的字段被复制到副本中的是引用类型的引用,而不是引用的对象,在副本中对引用类型的修改会影响源对象本身。
深拷贝:同样的是将所有字段复制到新的对象当中,不过,无论作为对象的值类型,还是引用类型,都会被重新创建和赋值,对于副本的修改,不会影响到对象的本身。
在C#中,如果你要实现浅拷贝或者深拷贝,微软都建议使用类型继承接口ICloneable接口的方式明确告诉调用者,该类型可以被拷贝。
浅拷贝
下面看看这个浅拷贝的例子
class Program { static void Main(string[] args) { MyClone mike = new MyClone { Name = "zz", Age = 10, Department = new Department() { Name = "it事业部" } }; MyClone rose = mike.Clone() as MyClone; Console.WriteLine(rose.Name); Console.WriteLine(rose.Department); Console.WriteLine(rose.Age); Console.WriteLine("开始改变mike的值"); mike.Age = 13; mike.Department.Name = "zzd"; mike.Name = "test"; Console.WriteLine(rose.Name); Console.WriteLine(rose.Department); Console.WriteLine(rose.Age); Console.ReadKey(); //上面很明确的说明了浅拷贝的作用,有值类型的性质的变量是很源对象是无关的,引用类型是和源对象关联在一起的 } } class MyClone:ICloneable { public string Name { get; set; } public int Age { get; set; } public Department Department { get; set; } public object Clone() { //浅拷贝 return this.MemberwiseClone(); } public void SayHello() { Console.WriteLine("深拷贝和浅拷贝"); } } public class Department { public string Name { get; set; } public override string ToString() { return this.Name; } }
深拷贝
那么如何实现深拷贝呢,最简单的办法就是一个个字段进行赋值,但是这种方法容易出错,因为你增加一个字段,减少一个字段的时候,那么拷贝的方法也要发生相关的变化,所以建议用序列化的形式来进行深拷贝。
public object Clone() { ////浅拷贝 //return this.MemberwiseClone(); using(Stream stream=new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(stream) as MyClone; } }
回到主题,原型设计模式和工厂模式一样都是属于创建型设计模式,原型返回的对象全部都是其本身的一个副本,复制品,但是工厂模式是new出来的对象,也可能是同一个对象。我们工作中的系统,工作周报就是一个模板,很典型的原型应用。
开始上班ing