C#实现原型模式
Posted 小小架构师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#实现原型模式相关的知识,希望对你有一定的参考价值。
原型模式是指通过拷贝原有对象来创建新的对象,以减少new一个新对象的资源开销。
今天我们就来看下如何在C#中使用原型模式,Follow me!
假如有这样一个需求:需要导出一万名学生资料到Excel中,一般代码会这样写:
上面的代码其实也没有什么问题,但如果数量级换成百万或千万,则频繁的创建对象会对性能造成很大的影响。而且学生对象中有部分字符都是一样的,比如Address。这时我们就需要使用原型模式来减少对象的创建了。在C#中其实就是使用ICloneable接口并实现Clone方法。代码如下:
上面的代码非常简单,主要调用当前对象的MemberwiseClone()方法,这个方法其实就是拷贝对象的内存流,我们看下源代码。如下:
我们接着改下使用的地方,将原来new的代码改成clone方法。代码如下:
上面的代码中,我们先new一个模板对象,然后以这个模板对象为基础,不停的拷贝产生新对象,这样就从new一万次变为new一次了,性能提升杠杠的。
到这里,C#中实现原型模式就讲完了,是不是特别简单?不过我们还要再补充一个点,就是浅拷贝和深拷贝,如果你对这块已经很了解了,就不用往下读了。想了解的继续,Follow me!
我们上面通过MemberwiseClone()方法实现的其实是对象的浅拷贝,大家应该都知道浅拷贝和深拷贝的区别。简单来说,如果对象的字段是复杂类型的话,浅拷贝只会拷贝这个字段的引用,而深拷贝会重新创建这个复杂类型的字段。
比如上面代码中学生的Address字段,就是一个复杂类型,通过Clone方法得到的一万个学生对象的Address其实都是指的同一个对象。如下图:
这样就会有问题,如果修改某一个学生的地址,则所有的学生地址都会变掉,这是我们不想看到的。如下:
对此,我们可以使用深拷贝来解决。一般实现深拷贝的方法有二进制序列化、反射等。我们先看下使用二进制序列化的方式,代码如下:
上面的代码中,我定义了一个IDeepCopy接口,然后让Student类实现它,在DeepCopy()方法中,我们使用BinaryFormatter操作流实现深拷贝。有一个地方要注意,就是Student类和Address类上面需要加上[Serializable]特性,不然不可以序列化的。
接着,我们再来讲一下使用反射来实现深拷贝,其实就是逐层遍历字段并赋值。代码如下:
这里定义了一个DeepCopyByReflect()泛型方法,这个方法中主要使用反射进行遍历每个字段,如果字段是复杂类型,则递归调用DeepCopyByReflect方法,直到所有的字段都为基本类型。
以上讲了二进制序列和反射方法实现深拷贝。其实我们也可以简单使用json序列化的方法,更简单,代码如下:
如果能帮到你一点点,就给个赞吧,或者关注我。
哈哈~~
以上是关于C#实现原型模式的主要内容,如果未能解决你的问题,请参考以下文章
设计模式之原型模式
C#设计模式:原型模式(Prototype)及深拷贝浅拷贝
C#设计模式——原型模式
C#设计模式:原型模式(Prototype Pattern)
c# 24种设计模式5原型模式(Prototype)
c#设计模式-创建性模式-3.原型模式