.java代码重构

前段时间读过martin fowler的《重构 ,改善既有代码的设计 》,不禁感叹:他老人家绝对对得起大师这个名号啊!对于入行不久的程序员来说,读这本书对提高代码质量肯定有帮助。就重构这个话题,还和部门同事做了次交流,将交流时的文档整理在此仅作备忘。

软件的成本
         N 年前, Yourdon 和 Constantine 在 Structured Design 一书中将经济学作为了软件设计的底层驱动力,软件设计应该致力于减少整体成本。  

      COST total = COST develop + COST maintain
      COST maintain = COST understand + COST change + COST test + COST deploy 

      软件的维护成本占了软件总成本的大部分,想要节约软件成本就要从软件的维护成本下手,而维护成本中理解老代码和修改老代码又占了绝大部分。可见,提高代码可理解性是多么重要,这时重构闪亮登场,为我们改善代码可读性提供了指导性的一些原则和手法。


  什么是重构
      看看 Martin Fowler的定义:

      在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。重构是一种有纪律的、经过训练的、有条不紊的程序整理方法,可以将整理过程中不小心引入错误的机率降到最低。本质上说,重构就是在代码写好之后改进它的设计。
                                                                                                                                       --Martin Fowler 

      重构 【 名词 】 :对软件内部结构的一种调整,目的是在不改变软件之可察行为 前提下,提高其可理解性,降低其修改成本 。

      重构 【 动词 】 :使用一系列重构准则(手法),在不改变软件之可察行为 前提下,调整其结构。


      关键的一点是重构离不开单元测试,测试驱动开发的模式。在已有单元测试的基础上进行代码重构,小步前进。

      另外一个比较好的建议是 Kent Beck所说的 两顶帽子 :使用重构技术开发软件时,你把自己的时间分配给两种截然不同的行为 : 「添加新功能」和「重构」。

重构的好处
•  使软件更容易理解
•  帮你找到 bug
•  提高编程速度
重构时机
•三次法则 
•添加新功能时
•Bugfix 时
•Code review 时 

重构与设计
      重构与设计并不是矛盾的,而是互为补充的:

•所有的设计都不可能做到滴水不漏,这个时候就需要重构来堵设计的漏洞;
•不能依赖重构而不重视重构。

重构与性能
      重构和性能优化是不同维度的手法,重构的目的是提示程序的可理解性和可维护性,而优化则是侧重提升性能。重构为了提高代码可读性往往还会导致性能不是最优,考虑“二八原则”,如果这段代码不会显著导致程序性能严重下降,我们选择重构。

坏味道及应对重构手法
• 重复的代码

–   提炼函数,提炼类,上移函数,塑造模板函数

• 过长函数

–   提炼函数,查询取代临时变量,函数对象取代函数,分解条件表达式

• 过大类

–   提炼类,提炼子类,提炼接口,以对象取代数据值

• 过长参数列

–   函数取代参数,引入参数对象,保持对象完整

•  发散式变化

–   提炼类

•  散弹式修改

–   搬移函数,搬移值域,将类内联

•  依恋情结

–   搬移函数,搬移值域,提炼函数

•  数据泥团

–   提炼类,引入参数对象,保持对象完整

•  基本型别偏执

–   以对象取代数据值,提炼类,引入参数对象,以对象取代数组,以类取代型别码,以子类取代型别码,以 State/Strategy 取代型别码

•  Switch 惊悚现身

–   多态取代嵌套条件表达式,以 State/Strategy 取代型别码,以明确函数取代参数

•  平行继承体系

–   搬移函数,搬移值域

• 冗余类

–   内联类,折叠继承体系

• 夸夸其谈未来性

–   折叠继承,将类内联,移除参数,重命名函数

• 令人迷惑的暂时值域

–   提炼类

• 过度耦合的消息链

–    隐藏委托

• 中间转手人

–   消除中间人,将函数内联,以委托取代继承

•  狎昵关系

–    搬移函数,搬移值域,改双向关联为单向,以继承取代委托,隐藏委托

• 异曲同工的类

–   重命名函数,搬移函数

• 不完美的类库

–   引入外加函数,引入本地扩展

•  单纯数据类

–    搬移函数,封装值域,封装集合

•  被拒绝的遗赠

–    以委托取代继承

•  过多的注释

–    提炼函数

重构法则分类
重新组织函数
•提炼函数
•将函数内联化
•将临时变量内联化
•以查询取代临时变量
•引入解释性变量
•剖解临时变量
•移除对参数的赋值操作
•以函数对象取代函数
•替换算法
在对象间搬移特性


•搬移函数
•搬移值域
•提炼类
•将类内联化
•隐藏委托关系
•移除中间人
•引入外加函数
•引入本地扩展
重新组织数据
•自封装值域
•以对象取代数据值
•将实值对象改为引用对象
•将引用对象改为实值对象
•以对象取代数组
•将单向关联改为双向
•将双向关联改为单向
•以符号常量或字面常量取代魔法数
•封装值域
•封装集合
•以数据类取代记录
•以类取代型别码
•以子类取代型别码
•以 State/Strategy 取代型别码
•以值域取代子类
简化条件表达式


•  分解条件表达式
•  合并条件表达式
•  合并重复的条件判断
•  移除控制标记
•以卫语句取代嵌套条件式
•  以多态取代条件式
简化函数调用
•重新命名
•重新命名函数
•查询和修改分离
•以明确函数取代参数
•保持对象完整 •以函数取代参数
•引入参数对象
•以工厂函数取代构造函数
•以异常取代错误码
•  将查询函数和修改函数分离   

处理概括关系

•值域上移
•函数上移
•函数下移
•值域下移
•构造函数本体上移
•提炼子类
•提炼超类
•折叠继承体系
•塑造模板函数
•以委托取代继承
•以继承取代委托


最后,附上ppt。[/size][/size]

 

猜你喜欢

转载自hongmingchun.iteye.com/blog/1606097