重构 刘发宾 2009-10-12
目录 <ul><li>为何重构? </li></ul><ul><li>何谓重构? </li></ul><ul><li>何时重构? </li></ul><ul><li>代码的坏味道 </li></ul><ul><li>测试 </li></ul><...
设计是有限制的,未来不可预知 桥梁史上最有名的事故之一。 美国华盛顿州 Tacoma Narrows 桥倒塌,这次事故令桥梁的设计规范重新修改, 风力和共振分析成为桥梁设计必不可少的一部分, 重构可以带来简单的设计,同时不损失其灵活性,这也降低...
设计编码是人类的活动 软件开发首先是一场沟通博弈,重构就是在代码写好之后改进它的设计 有了设计,我可以思考的更快,但是其中充满了小漏洞 1300 年赵州桥与现代“豆腐渣工程”
管理软件的复杂度 程序的规模 程序的复杂度 程序员的工作就是保持程序的复杂度与规模的关系尽量接近线性函数,而不是指数函数,最小的复杂度,不要让无谓的复杂度快速的增长 亚里斯多德的” 事物的本质性质和附属性质”,本质复杂性解决问题核心。致力于本质...
需求多变杂 小的改动不容忽视,层出不尽 封装,隔离变化
Double B  (bug bad smell) Refactoring  是一个  code review  和反馈的过程。在另一个时段重新审视自己或别人代码,可以更容易的发现问题和加深对代码的理解, Refactoring  是一个良好的...
重构的效益 <ul><li>改进软件设计 重构是的设计在代码中演化和完善,和设计彼此互补,程序员对代码所做的为了满足短期利益代码改动,或再没有完全清楚增个架构下的改动,都很容易是代码失去它的清晰结构,偏离需求或设计。而这些改动的积累很容易使代码...
何谓重构
概念的定义 <ul><li>Refactoring is the process of changing a software system in such a way that it does not alter the external b...
重构是一种方法论 牛顿万有引力定律无法解释水星运动的不规则形象,爱因斯坦构建的广义相对论理论即向下兼容了牛顿定律,又满足新的需求—自然的探索 数学系统的一直在重新构建,解决危机:有理数 ,无理数,实数,虚数, 欧几里德几何,笛卡尔的解析几何,黎...
重构和设计模式 <ul><li>设计模式为重构提供了目标,但不是目的。 </li></ul><ul><li>设计模式是经过证实的在一定场景下解决一般设计问题的解决方案的核心,通过设计模式我们很好得解决了某种问题,并且便于我们思考和交流,降低沟通...
何时重构 ? 重构本来就不是一件特别拨出时间做的事情,重构应该随时随地进行,你不应该为重构而重构,你之所以重构,是因为你想做别的事,而重构可以帮助你把那些事情做好。 <ul><li>添加功能,现有代码的设计无法帮助我轻松的 添加我需要的功能,如...
代码的坏味道 <ul><li>Duplicated code  重复的代码   Extract Method,Pull up Method,Template Method. </li></ul><ul><li>Long method, Clas...
测试 <ul><li>Dcut-------design-code-unit test  RT RT RT </li></ul><ul><li>确保所有测试自动化,让他们检查自己的测试结果 </li></ul><ul><li>编写未完善的测试并...
原则 <ul><li>一些设计类的原则 </li></ul><ul><li>尽量简单原则:尽可能的简单  </li></ul><ul><li>隔离变化:区分出系统中变与不变 的部分。  </li></ul><ul><li>开闭原则:对修改关闭,...
如何重构 <ul><li>重新组织你的方法 </li></ul><ul><li>在对象之间搬移特性  </li></ul><ul><li>简化条件表达式  </li></ul><ul><li>重新组织你的 对象  </li></ul><ul><...
重新组织你的方法
Extract Method
Inline Method <ul><li>Int getRating(){ </li></ul><ul><li>return (moreFiveLateDeliveries()) ? 2 : 1; </li></ul><ul><li>} </...
Replace Temp with Query
Introduce Explaining Variable
Split Temporary Variable
Remove Assignments to Parameters
Replace Method with Method Object
Substitute Algorithm
Remove Double Negative
Reduce Scope of Variable
Replace Iteration with Recursion
Replace Assignment with Initialization
Replace Static Variable with Parameter
Reverse Conditional
Split Loop
在对象之间搬移特性
Move method
Move Field
Extract Class
Inline Class
Hide Delegate
Remove Middle Man
Introduce Foreign Method
重新组织数据
Self Encapsulate Field
Replace Data Value with Object
<ul><li>Change Value to Reference   </li></ul><ul><li>Change Reference to Value   </li></ul><ul><li>Replace Array with Obj...
简化条件表达式
Decompose Conditional 分界表达式
Consolidate Conditional Expression 合并
Consolidate Duplicate Conditional Fragments
Replace Nested Conditional with Guard Clauses
Replace Conditional with Polymorphism 多态
Introduce Null Object
Introduce Assertion
简化函数调用 <ul><li>Rename method </li></ul><ul><li>Add/remove parameters </li></ul><ul><li>Separate query from modifier </li><...
处理概括关系
Pull Up Field
Pull Up Method
Pull Up Constructor Body
Push Down Method
Push Down Field
Extract Superclass
Extract Interface
Extract Subclass
Collapse Hierarchy 折叠继承体系
Form Template Method
Replace Inheritance/ Delegation with Delegation/Inheritance
大型重构 <ul><li>梳理并分解继承体系 </li></ul><ul><li>将过程化转化为对象化 </li></ul><ul><li>将领域和表述 / 显示分离 </li></ul><ul><li>提炼集成体系 </li></ul>
总结 <ul><li>带给我们思考,不需要记住,可以当成字典,主要是学习重构名录方法,思想,如何遵守一些编码准则。 </li></ul><ul><li>重构并不高深,很简单,我们都在用,只是我们不够系统,不够专业 </li></ul>
评价经典的书 <ul><li>参考和学习: </li></ul><ul><li>http:// www.refactoring.com/catalog/index.html </li></ul><ul><li>http://c2.com/cgi...
Upcoming SlideShare
Loading in …5
×

Refactoring 重构

1,676 views

Published on

重构

  • Be the first to comment

Refactoring 重构

  1. 1. 重构 刘发宾 2009-10-12
  2. 2. 目录 <ul><li>为何重构? </li></ul><ul><li>何谓重构? </li></ul><ul><li>何时重构? </li></ul><ul><li>代码的坏味道 </li></ul><ul><li>测试 </li></ul><ul><li>重构名录 </li></ul>
  3. 3. 设计是有限制的,未来不可预知 桥梁史上最有名的事故之一。 美国华盛顿州 Tacoma Narrows 桥倒塌,这次事故令桥梁的设计规范重新修改, 风力和共振分析成为桥梁设计必不可少的一部分, 重构可以带来简单的设计,同时不损失其灵活性,这也降低了设计过程的难度,减轻了设计的压力
  4. 4. 设计编码是人类的活动 软件开发首先是一场沟通博弈,重构就是在代码写好之后改进它的设计 有了设计,我可以思考的更快,但是其中充满了小漏洞 1300 年赵州桥与现代“豆腐渣工程”
  5. 5. 管理软件的复杂度 程序的规模 程序的复杂度 程序员的工作就是保持程序的复杂度与规模的关系尽量接近线性函数,而不是指数函数,最小的复杂度,不要让无谓的复杂度快速的增长 亚里斯多德的” 事物的本质性质和附属性质”,本质复杂性解决问题核心。致力于本质复杂性,去除附属复杂性。 1 噢卡姆剃刀原理:对一现象的好多种解释,最简单的往往是正确的,如无必要,务增复杂性。 2 迪米特法则 : 只跟最亲密的朋友讲话。任何对象不需要制定与之交互的那些对象的实现细节,减少复杂度 高内聚,松耦合
  6. 6. 需求多变杂 小的改动不容忽视,层出不尽 封装,隔离变化
  7. 7. Double B (bug bad smell) Refactoring 是一个 code review 和反馈的过程。在另一个时段重新审视自己或别人代码,可以更容易的发现问题和加深对代码的理解, Refactoring 是一个良好的软件开发习惯,问题越是发现在前端,软件修复以及维护成本会越低 ,问题越是发现在后端,成本越来越高
  8. 8. 重构的效益 <ul><li>改进软件设计 重构是的设计在代码中演化和完善,和设计彼此互补,程序员对代码所做的为了满足短期利益代码改动,或再没有完全清楚增个架构下的改动,都很容易是代码失去它的清晰结构,偏离需求或设计。而这些改动的积累很容易使代码偏离它先设计的初衷而变得不可立即和无法维护。 </li></ul><ul><li>使软件更容易理解 程序第一是写给人看的,而不是写给机器看的 , 代码被阅读的和被修改的次数远远多于他被编写的次数 </li></ul><ul><li>助你提高编程速度 良好的设计是维持开发速度的根本,重构帮助你快速地开发软件,阻止系统腐败变质,提高设计质量 </li></ul>叫我如何不喜欢你!!!! 脆弱 坚硬
  9. 9. 何谓重构
  10. 10. 概念的定义 <ul><li>Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. – MartinFowler </li></ul><ul><li>Refactoring is typically done in small steps. After each small step, you're left with a working system that's functionally unchanged. Practitioners typically interleave bug fixes and feature additions between these steps. So refactoring doesn't preclude changing functionality, it just says that it's a different activity from rearranging code. </li></ul><ul><li>名词:对软件结构的一种调整;目的是在 不改变软件之可察行为 ,提高可理解性,降低其修改成本。 </li></ul><ul><li>动词:使用一系列重构准则,在 不改变软件之可察行为 前提下,调整其结构。 </li></ul><ul><li>两顶帽子:添加新功能,重构。交替进行。 </li></ul><ul><li>重构不是灵丹妙药,不是什么银弹,但是它是一把银钳子 ,测试,小修改,测试,小修改 </li></ul><ul><li>重构不只是整理代码,高效且受控的代码整理技术,有一定重构准则。 </li></ul>概念——判断——逻辑,概念是抽象的结果,使得我们可以忽略细节,使得我们有限的心灵可以记忆管理更复杂更多的事情,定义了概念也方便我们交流沟通 概念还是要知道地!!!!
  11. 11. 重构是一种方法论 牛顿万有引力定律无法解释水星运动的不规则形象,爱因斯坦构建的广义相对论理论即向下兼容了牛顿定律,又满足新的需求—自然的探索 数学系统的一直在重新构建,解决危机:有理数 ,无理数,实数,虚数, 欧几里德几何,笛卡尔的解析几何,黎曼几何, 乔治康拓的集合轮 重构也是我们认识世界,改造世界的方法论 .
  12. 12. 重构和设计模式 <ul><li>设计模式为重构提供了目标,但不是目的。 </li></ul><ul><li>设计模式是经过证实的在一定场景下解决一般设计问题的解决方案的核心,通过设计模式我们很好得解决了某种问题,并且便于我们思考和交流,降低沟通之间的理解误差,此外同样重要的,设计模式增强了可复用性,便于将来扩展和维护。 </li></ul><ul><li>设计模式是内功,《九阳真经》、《易筋经》 、 《葵花宝典》 、重构是外功,小区里的太极拳。 </li></ul>
  13. 13. 何时重构 ? 重构本来就不是一件特别拨出时间做的事情,重构应该随时随地进行,你不应该为重构而重构,你之所以重构,是因为你想做别的事,而重构可以帮助你把那些事情做好。 <ul><li>添加功能,现有代码的设计无法帮助我轻松的 添加我需要的功能,如果用某种设计添加代码会简单很多,隔离变化点 </li></ul><ul><li>修改错误,改变代码结构有利于我们找到臭虫。关注产生 bug 点 </li></ul><ul><li>复审代码 </li></ul><ul><li>Bad smell </li></ul><ul><li>程序的两面价值观: </li></ul><ul><li>今天可以为你做什么? </li></ul><ul><li>明天可以为你做什么? </li></ul><ul><li>什么程序让我们难以想与? </li></ul><ul><li>难于阅读的程序 </li></ul><ul><li>逻辑重复的程序 </li></ul><ul><li>添加新行为时需要修改既有代码者 </li></ul><ul><li>带有复杂条件逻辑的程序 </li></ul><ul><li>设计本身就是错误的,应该重做,不应该重构 </li></ul><ul><li>已经是发布阶段了,为了稳定性,不应再重构 </li></ul><ul><li>已经是项目的后期了,如果重构可能会使项目延期,给项目带来很大冲击。 </li></ul><ul><li>如果没有十足把握,不进行重构 </li></ul>
  14. 14. 代码的坏味道 <ul><li>Duplicated code 重复的代码 Extract Method,Pull up Method,Template Method. </li></ul><ul><li>Long method, Class,Parameter list 过长方法, 类,参数 Extract Method ,Replace Temp with Query,Introduce parameter,Extract Class Extract Subclass Preserve Whole Object </li></ul><ul><li>Divergent Change 发散式变化 class 因不同原因在不同方向变化,一种变化导致类内修改几个函数, extract class </li></ul><ul><li>Shotgun Surgery 霰弹式变化 一个变化需要到不同的类去做修改,散布各处 Move Method Move Field,Inline Class </li></ul><ul><li>Feature Envy 依恋情结 一个类内的函数过多的调用另外类的函数, Move Method Extract Method </li></ul><ul><li>Data Clumps 数据泥团 多个地方看到相同数据项,两个类内相同值域 Extrat Method </li></ul><ul><li>Primitive Obsession 基本性别偏执 ,基本数据类型,结构型别 , struct 和 int , replace data alue object replae type code with class </li></ul><ul><li>Switch Statements switch 语句在于重复 , 分散在各处的 switch 多态解决 replace type code with subclass , introduce null object </li></ul><ul><li>Parallel inheritance hierarchies 平行集成体系 每当你为一个 class 增加一个 subclass ,也不许为另外一个增加一个 subclass Move Mothed Move Field </li></ul><ul><li>Lazy Class 冗赘类 可以去掉的类 Inline class Collapse Hierarchy </li></ul><ul><li>Specultive Generality 夸夸其谈未来性 企图用特殊情况来处理一些非必要的事情,过度设计, rename method , remove parameter test cases </li></ul><ul><li>Temporary Field 令人迷惑的暂时值域 , introduce null object </li></ul><ul><li>Message Chains 过度耦合的消息链 hide degate move method extract method </li></ul><ul><li>Middle Man 中间转手人,过多使用 delegation 委托 。 Replace delegation with inheritance InlineMethod </li></ul><ul><li>Inappropriate intimacy 狎昵关系 两个 class 过分关注彼此的 private 。 Move method move field hide delegate </li></ul><ul><li>Alternative classes with different interfaces 异曲同工类 函数做同样的功能,名字不同 rename method </li></ul><ul><li>Incomplete livray class 别人的类库过度设计 , move method introduce foreign method introduce local extension </li></ul><ul><li>Data class 纯稚的数据类 拥有值域,一起读写这些的函数,别的什么也没有。 Encapsulate field , remove setting method hide method </li></ul><ul><li>Refused bequest 被决绝的馈赠 subclass 继承 superclass 函数和数据 不想喝不需要继承, push down method push down field </li></ul><ul><li>Comments 过多的注释 注释很好,代码很糟糕,当你感觉需要撰写注释时,请先尝试重构,试着让所有注释都变得多余 </li></ul>
  15. 15. 测试 <ul><li>Dcut-------design-code-unit test RT RT RT </li></ul><ul><li>确保所有测试自动化,让他们检查自己的测试结果 </li></ul><ul><li>编写未完善的测试并实际运行,好过对完美测试的无尽等待 </li></ul><ul><li>考虑可能出错的边界条件,把测试的活力集中在哪儿 </li></ul>
  16. 16. 原则 <ul><li>一些设计类的原则 </li></ul><ul><li>尽量简单原则:尽可能的简单 </li></ul><ul><li>隔离变化:区分出系统中变与不变 的部分。 </li></ul><ul><li>开闭原则:对修改关闭,对扩展开放 </li></ul><ul><li>单一职责原则:只能让一个类有且仅有一个职责 </li></ul><ul><li>接口隔离原则:使用多个专门的接口比使用单一的总接口总要好,遵循最小接口原则。 </li></ul><ul><li>依赖倒置原则:高层模块不应该依赖于低层模块,二者都应该依赖于抽象,抽象不应该依赖于细节 </li></ul><ul><li>里氏替换原则:子类应当可以替换父类并出现在父类能够出现的任何地方 </li></ul><ul><li>不要和陌生人说话 </li></ul><ul><li>编程原则的讨论 </li></ul><ul><li>KISS – Keep It Simple Stupid </li></ul><ul><li>DRY – Don’t Repeat Yourself </li></ul><ul><li>写代码时时刻设想你就是将来要来维护这坨代码的人 </li></ul><ul><li>最好设想你的代码会被一个挥着斧头的精神病来维护。 </li></ul><ul><li>不要重新发明轮子 </li></ul><ul><li>利用分治、抽象,解开子问题之间的耦合。 </li></ul>大自然优秀的面向对象设计师 , 程序员对宇宙人生,须入乎其内,又须出乎其外。入乎其内,故能写之。出乎其外,故能观之。入乎其内,故有生气。出乎其外,故有高致
  17. 17. 如何重构 <ul><li>重新组织你的方法 </li></ul><ul><li>在对象之间搬移特性 </li></ul><ul><li>简化条件表达式 </li></ul><ul><li>重新组织你的 对象 </li></ul><ul><li>简化函数调用 </li></ul><ul><li>处理概括关系 </li></ul>
  18. 18. 重新组织你的方法
  19. 19. Extract Method
  20. 20. Inline Method <ul><li>Int getRating(){ </li></ul><ul><li>return (moreFiveLateDeliveries()) ? 2 : 1; </li></ul><ul><li>} </li></ul><ul><li>Boolean moreFiveLateDeliveries() { </li></ul><ul><li>return _numberOfLateDeliveries > 5; </li></ul><ul><li>} </li></ul>Int getRating(){ return (_numberOfLateDeliveries > 5) ? 2: 1 }
  21. 21. Replace Temp with Query
  22. 22. Introduce Explaining Variable
  23. 23. Split Temporary Variable
  24. 24. Remove Assignments to Parameters
  25. 25. Replace Method with Method Object
  26. 26. Substitute Algorithm
  27. 27. Remove Double Negative
  28. 28. Reduce Scope of Variable
  29. 29. Replace Iteration with Recursion
  30. 30. Replace Assignment with Initialization
  31. 31. Replace Static Variable with Parameter
  32. 32. Reverse Conditional
  33. 33. Split Loop
  34. 34. 在对象之间搬移特性
  35. 35. Move method
  36. 36. Move Field
  37. 37. Extract Class
  38. 38. Inline Class
  39. 39. Hide Delegate
  40. 40. Remove Middle Man
  41. 41. Introduce Foreign Method
  42. 42. 重新组织数据
  43. 43. Self Encapsulate Field
  44. 44. Replace Data Value with Object
  45. 45. <ul><li>Change Value to Reference </li></ul><ul><li>Change Reference to Value </li></ul><ul><li>Replace Array with Object </li></ul><ul><li>Duplicate Observed Data </li></ul>
  46. 46. 简化条件表达式
  47. 47. Decompose Conditional 分界表达式
  48. 48. Consolidate Conditional Expression 合并
  49. 49. Consolidate Duplicate Conditional Fragments
  50. 50. Replace Nested Conditional with Guard Clauses
  51. 51. Replace Conditional with Polymorphism 多态
  52. 52. Introduce Null Object
  53. 53. Introduce Assertion
  54. 54. 简化函数调用 <ul><li>Rename method </li></ul><ul><li>Add/remove parameters </li></ul><ul><li>Separate query from modifier </li></ul><ul><li>Param eterize method 函数带参数 </li></ul><ul><li>Replace param eter with explicit method 明确函数取代参数 </li></ul><ul><li>Preserve whole object 保持对象完整 </li></ul><ul><li>Repalce parameter with methods </li></ul><ul><li>Introduce parameter object </li></ul><ul><li>Remove setting method </li></ul><ul><li>Hide method </li></ul><ul><li>Replace contructor with factory method </li></ul><ul><li>Encapsulate downcast </li></ul><ul><li>Replace error code with exception </li></ul><ul><li>Replace exception with test </li></ul>
  55. 55. 处理概括关系
  56. 56. Pull Up Field
  57. 57. Pull Up Method
  58. 58. Pull Up Constructor Body
  59. 59. Push Down Method
  60. 60. Push Down Field
  61. 61. Extract Superclass
  62. 62. Extract Interface
  63. 63. Extract Subclass
  64. 64. Collapse Hierarchy 折叠继承体系
  65. 65. Form Template Method
  66. 66. Replace Inheritance/ Delegation with Delegation/Inheritance
  67. 67. 大型重构 <ul><li>梳理并分解继承体系 </li></ul><ul><li>将过程化转化为对象化 </li></ul><ul><li>将领域和表述 / 显示分离 </li></ul><ul><li>提炼集成体系 </li></ul>
  68. 68. 总结 <ul><li>带给我们思考,不需要记住,可以当成字典,主要是学习重构名录方法,思想,如何遵守一些编码准则。 </li></ul><ul><li>重构并不高深,很简单,我们都在用,只是我们不够系统,不够专业 </li></ul>
  69. 69. 评价经典的书 <ul><li>参考和学习: </li></ul><ul><li>http:// www.refactoring.com/catalog/index.html </li></ul><ul><li>http://c2.com/cgi/wiki?WhatIsRefactoring </li></ul><ul><li>http://c2.com/cgi/wiki?WikiPagesAboutRefactoring </li></ul><ul><li>http:// en.wikipedia.org/wiki/Code_refactoring </li></ul><ul><li>http://www.slideshare.net/liufabin66688/refactoring-and-unit-testing </li></ul><ul><li>http://www.slideshare.net/liufabin66688/refactoring-example </li></ul><ul><li>http://www.slideshare.net/liufabin66688/refactoring-simple-example </li></ul><ul><li>http://www.slideshare.net/liufabin66688/lecture28 </li></ul>

×