典型案例
下面列举了一些eMAN系统(前台部分)中较常见的代码质量问题。我们没有列出一些更常见的“坏味道”(例如大类、长方法等),因为Martin Fowler在《重构》一书中已经把它们描述得足够清楚,而且针对它们的重构也相对容易。本文中列出的是一些相对规模较大、较为复杂的情形。
我们相信类似的情形也存在于很多其他系统中,但我们并不打算宣称这个列表足以包治百病。大规模重构是一件极其复杂的细致活,很多时候你需要根据当前情况寻找适合自己的解决方案。
无法在测试环境中创建被测对象
对象在创建过程中自己尝试获得所需的依赖对象,就可能在单元测试环境下因无法创建依赖对象而导致被测对象的创建失败,从而不能把被测对象放进单元测试。例如AuthorizationService类的创建过程如下:
|
在单元测试环境下SecurityBaseModule.getSecuityModuleRef()返回null,因此尝试创建AuthorizationService会抛出NullPointerException异常。
重构办法:
通过构造函数的参数传入依赖对象,而不自己创建。
使用被测对象的地方负责创建依赖对象。随着重构进行把这一责任不断上推。
把初始化动作与构造函数分开,构造函数只用于获得依赖关系。如果还需要更复杂的初始化动作,在单独的初始化函数中进行。
重构目标:
通过调用构造函数、传入null作为依赖对象引用,能在单元测试中创建被测对象。
无法在测试环境中运行被测方法
如果被测方法在计算过程中自己尝试获得所需的依赖对象,就可能在单元测试环境下因无法满足依赖对象的要求而导致测试失败,从而无法对希望测试的方法进行单元测试。例如SessionManager.isAdminGroupUser方法如下:
|
在单元测试环境下RpcInvoker的调用尝试必定会抛出异常,于是对isAdminGroupUser方法的调用必定会返回false。如果让RpcInvoker通过网络进行真实的RPC调用,不仅工作量大,使测试不可靠,而且这样的测试实际上主要是在测RpcInvoker的工作是否正确,变成了集成测试而不是SessionManager的单元测试。
重构办法:
通过构造函数的参数传入依赖对象并保存在成员变量中,需要使用依赖对象时通过成员变量调用。被测方法不直接创建依赖对象。
使用被测对象的地方负责创建依赖对象。随着重构进行把这一责任不断上推。
单元测试中用mock框架(推荐JMock)创建依赖对象。在每个测试案例(即测试方法)中独立设置对mock对象的期望,发现明显的重复时再抽取公共代码。
重构目标:
通过调用构造函数、传入mock对象,能在单元测试中创建被测对象。
对mock对象设置适当的期望,能调用被测方法,并覆盖到正常和异常路径。
不恰当的对象获取方式
不必要的Singleton模式。如果一个对象本身没有内部状态,只是根据外界状态进行计算,这样的对象不需要是Singleton的。例如CommonTool类和SessionService类:这两个类只是把请求转发给其他对象处理,它们不需要使用Singleton模式。
通过其他对象获取。从其它对象中取出自己需要的依赖对象,“由谁提供某个对象”的决策相当随机,有时通过一条长链来获得自己真正需要的依赖对象。例如要得到RightPaneXMLParser对象,就需要通过下列方式:
|
重构办法:
如前所述,对象所需的依赖对象全部以构造函数参数的形式获得,将“创建对象”的责任不断上推,直至系统顶端的某个位置聚集了系统中绝大部分的对象创建逻辑。
在系统顶端分离出一个全局工厂对象,该对象负责创建系统中所有的对象,并组装对象之间的依赖关系。其他地方原则上不作对象创建。
在少数不直接被这个系统顶端调用的地方(例如对外暴露给第三方的接口),从全局工厂请求自己需要的对象。
引入轻量级IoC容器(建议在PicoContainer和Spring Core之间选择),替代这个全局工厂对象。
重构目标:
系统中主要业务对象的创建都在全局工厂进行。
业务对象是否Singleton能够以配置的方式管理。
| 共4页: 上一页 [1] [2] 3 [4] 下一页 | ||||||
|
|
||||
| · 2007年互联网大会 · 华为员工自杀频频拷问.. · 技术人求职简历完备手册 · 勇闯IT培训黑色围城 · 北漂技术人90天求职纪实 · 龙芯要做中国的“奔腾” · 国际文档格式标准开战 · 贝恩资本携手华为22亿.. |
· 隐私保护技术探讨 · Windows Server 2008专.. · NAC安全访问控制 · PHP开发应用手册 · ASP.NET 2.0基础开发指.. · WCF开发基础 · 路由器设置与口令恢复 · VC++基础开发专题 |
|||
|
||||
| · iSCSI应用与发展 · SQL Server 2008/2005.. · SOA 面向服务架构 · SQL Server 2008/2005.. · iSCSI应用与发展 · RAID——磁盘阵列基础 · 中间件应用技术专题 · SQL Server入门到精通 |
· 病毒查杀专题 · 国际文档格式标准开战 · Linux防火墙 · 路由器设置与口令恢复 · 打造安全服务器 · SOA 面向服务架构 · PHP开发应用手册 · ADSL应用面面俱到 |
|||
|
||||
| · iSCSI应用与发展 · 中间件应用技术专题 · SQL Server入门到精通 · SQL Server 2008/2005.. · SOA 面向服务架构 · iSCSI应用与发展 · RAID——磁盘阵列基础 · 身份认证技术 |
· 病毒查杀专题 · 清除流氓软件——51CTO.. · 路由器设置与口令恢复 · SOA 面向服务架构 · 了解统一威胁管理(UTM).. · ADSL应用面面俱到 · ADSL应用面面俱到 · 反垃圾邮件技术应用 |
|||