2.3.4注重性能的编码方式
在编写代码时,要保持资源释放的警惕性,时刻提醒自己如何提高性能,至少要做到减少无辜资源的浪费。要做到上述几点,其实最重要的就是资源的释放,不及时释放资源极易导致服务器内存被吃光的危险。
这里我们介绍几种资源使用和释放的方法,只要适当地运用,就可以大大减少内存出问题的可能性。
1。在对象使用时再实例化
对象在使用时再实例化,而不是在类加载的时候就实例化。可以把实例化的工作放在构造函数中或者初始化的方法中,如果不是及时需要的对象,建议使用延迟加载的方式。
2.在对象不使用时及时设置为NULL
当对象不需要再使用时,应该在第一时间内将其设置为NULL,这样可以方便GC:及时地回收该对象所占用的内存。
.NETGc算法用的并不是“引用计数”,而是“标记与清除”,所以你不必担心你所设置为NuLL的对象是否会被及时地回收。“标记与清除”算法是从应用程序域的根对象开始计算一个对象可达树。显然,如果是不能够被访问的对象就会被.NETGc认为是垃圾,将被回收掉。而“引用计算”算法,是计算每个对象的引用计数,所以哪怕这个对象有任何一个引用关系存在,都不会被释放掉,这种算法经常会导致内存泄漏。而.NETGC的“标记与清除”算法不会管你的引用关系,哪怕有一群对象彼此互相连接,但是这群对象是孤立的,从应用程序域根对象开始计算可达树,只要中问断开了与这群对象的可达,那么这群对象同样会被.NETGc回收。
3.使用IDisposable接口来声明有重要资源需要及时释放
IDisposable接口是用来声明该对象内部有重要的资源需要在不使用时及时释放的,像数据库连接、消息池对象,这些都是很重要、很有限的系统资源。如果稍微使用不当,这些关键性的对象会立马让系统整体瘫痪、内存吃光或者cPul00%处理中,而你为了定位具体是哪个对象在使用时出了问题,就不得不使用WinDebug,之类的工具去仔细地查看对象的内存状态和cPu状态。
尤其是当对象使用到了本地非托管资源时,一定要记住及时地实现IDisposable接口,而使用者也一定要及时地调用IDisposable.Dispose()方法或者使用using()语句来自动地释放资源。
2.4单元测试、可测试性代码、持续重构
本节将介绍单元测试的意义,让大家明白重构是需要单元测试作为保障才得以实施的。大部分开发人员不明白单元测试的意义,也不懂得如何去写单元测试,所以也就谈不上把重构运用到项目的开发中去。
本节将循序渐进地勾画出重构与单元测试之间的艺术性,让大家彻底明白单元测试技术的重要性。
为了更好地理解本节内容,我们最好带着以下问题来阅读。
第一,你是否曾想过对某段逻辑进行重构,但是不敢改?
第二,你是否曾抱着很多设计模式、重构模式满怀信心地准备进行大面积的代码修改,结果却是无法下手对以往代码做任何微小修改?是不是会觉得自己所学的这些技术没有什么实际用处,从而导致你对学习失去了信心?
第三,你是否无法深刻理解敏捷开发到底改变了现在开发的哪些方面,到底敏捷在哪里?
第四,你是否无法明白别人所说的“持续重构出核心领域模型”的过程到底是怎样的?
如果你有上述疑问,那么学习本节内容之后,这些问题就会迎刃而解。
2.4.1单元测试的重要性及核心意义
首先需要说明的是,单元测试并不只是为了验证你目前所写的代码有没有问题,它更为重要的作用是,你一次编写好的测试用例是否可以在日后随时随地地运行,来验证你本次所修改的代码是否影响到了以往的业务逻辑。单元测试是一种保证你所写的代码在整个生命周期中都不会出BUG的防护墙,是具有重要价值的软件过程制品之一。
正是因为可以在日后随时随地保证代码的质量,所以我们就可以随时随地地进行重构,而不需要害怕自己的修改是否会使以往的代码出现BuG。毕竟大部分情况下我们都是在维护一个大型的系统,大型系统的生命周期很漫长,中间会有新功能的添加和旧功能的重构,所以单元测试是非常需要的,应该引起重视。如果没有单元测试,很难保证代码在一两年之后还是清晰的,那就百谈不卜“价值”二字了。
……