重构心得

来源:互联网 发布:刘诗雯丁宁关系知乎 编辑:程序博客网 时间:2024/05/15 22:16
风行水上
blast2001@21cn.com
2006-1-6

 

 

最近阅读并参加了公司组织的“重构大赛”, 虽然没搞到名次, 但是总算身体力行实践了一把, 颇有感触 ^-^. 
写下一点东西, 纯当学习总结。

重构的概念/含义:
本质上, 就是[在代码写好之后改进它的设计]-----代码整理, 其实大部分程序员经常由于各种原因会调整/改写一些代码, 
只不过大家以前是零散的、目的性不强的操作, 而老外[Martin Flower]等人把这个理论化, 系统化了。
不得不佩服那几个大师级人物, 人家牛得我们望尘莫及啊 !^-^

定义:对软件内部结构的一种调整, 目的是在不改变[软件可察行为](外观功能)的前提下, 改善程序结构, 提高可读性,使之更易于修改。

一旦我们有了良好的代码,那我们还惧怕什么,什么都可以轻松搞定。


1)重构以设计模式作为目标。重构中要逐渐向模式靠拢。
设计模式是指对在类似的环境中的某一局部不断出现的问题, 提供了解决方案。 模式一旦总结出来后,在类似的情景中就可以直接复用,
有点类似围棋中的定式。从更高的层次来看, 设计模式很大部分是OO原则和设计理念的具体表现形式。
什么时候俺也能达到见山非山而山, 见水非水而水啊 :)

2)重构以单元测试做为保障, 要频繁运行自动化的单元测试。
以前我总是把很多功能一下子写完,然后一把调试,结果花在调试的时间很长, 总的效率不高(身处一堆不可信的代码丛中, 要找出错误太难了, 调试的栈很深, 怀疑的点很多)。
Martin Flower建议应该完成一点功能同时也要完成相应的测试用例, 测试一下,保证每次新写的代码都能正确运行(可信赖的),从而当代码写完了,系统也基本调试完毕了, 
从前期看可能写代码的效率不高(因为要建立测试用例并进行测试), 但从总体来看, 总的效率反而增高了。 测试能够自动化运行并检查结果, 可以很快找到新代码中的错误。
真可以算是一老永逸, 先苦后甜啊, 让计算机这个不知疲倦的家伙干活去吧, 我们应该把时间更多的用于有创造性的活动上, 例如 泡MM :)

3)重构要以小步前进, 积少成多, 累积小修小改为根本改善设计质量。
跨大步的话风险太大, 而且增加了rollback的难度(经理或管理层几乎不可能同意在代码写好之后搞大改)。
这有点类似于在抗战中, 由于条件有限, 我们就小块小块的敲鬼子, 直到把这个牛皮糖敲完。
这个类比好像不太恰当, 呵呵 !

4)重构倾向于减小类型的规模------>分而治之为小型对象和函数。
小规模由更好的复用性(共享能力), 职责更明确, 内聚度更高。
OO中很强调系统内职责(类型的契约和义务)的独立和清晰, 类型中的逻辑不能过于复杂, 否则将严重降低可读性。
当然这个分解也不能走极端, 还是有个度的问题, 过犹不及嘛。
一个好的软件系统是各种因素权衡的结果,也就是你如何把握一个度的问题, 切忌为了“重构”而进行重构。


5)重构的许多具体方法都是在OO原则和GRASP模式等高层范畴的指导和细化下得出的。 如GRASP模式中的信息专家模式和不要和陌生人讲话等,
  和重构中的异曲同工, 只不过表面的提法不同而已。
  
 
6) [Martin Flower]强调:是否进行重构以及重构的粒度依赖于个人的直觉和经验。
重构它只是一种手段不是我们的最终目的, 并不像考试有严格的对错之分, 在很多情况下没有唯一正确的答案。
[Martin]也只是给我们提出了一些常用的重构准则和手法, 具体实施要靠本人定夺。

而且重构中很多方法之间是互为反向过程,如提炼类(Extract Class)和将类内联化(Inline Class)互为反向过程.
具体应用哪些方法在一定程度上依赖于所处的上下文情景/环境。

7) 重构强调的一个重要方面: 消除重复或相似度很高的代码, 包括逻辑重复。
Say everything Once And Only Once.
将所有事物和行为都只表达一次,唯一一次,这正是优秀设计的根本.

8)[Dennis]:计算机科学是这样一门学科, 它相信所有的问题都可以通过多一个间接层来解决。
这句话道出了很多设计原则和理念的本质, 可以说是高屋建瓴的经典语录。
不仅重构会引入间接层, 在前期设计中亦如此。 设计模式中的很多方法也是在添加了间接层/中间层才能实现。
当然, 间接层这也是把双刃剑, 在修炼中水平不足的话难免伤到自己。搞软件很多时候都是在玩平衡, 而且是那种微妙的平衡。


花了一个多小时, 终于写完了。 太久没有写东西了, 书面表达能力下降了很多, 看来以后还得常写。

原创粉丝点击