Guest User

Untitled

a guest
Jun 19th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.97 KB | None | 0 0
  1. # Refactoring
  2.  
  3. ## What is Refactoring?
  4.  
  5. >The external behavior of the system does not change while the internal structure of the system is improved.
  6.  
  7. Sometimes called "Improving the design after it has been written" or "Improving the design of existing code",the purpose is to make software easier to understand and modify
  8.  
  9. + **Benefits**
  10. + Code size **reduced** after refactoring
  11. + Confusing structures are transformed into **simpler** structures(Easier to maintain)
  12.  
  13.  
  14. + **How to make refactoring safe?**
  15. + Use refactoring "patterns"
  16. + Test constantly,write test before write code,and after refactoring,run the tests and check they all pass.
  17.  
  18. ## Why should you refactor?
  19.  
  20. - Improve the design of software
  21. - Makes software easier to understand
  22. - Helps find bugs
  23. - Helps program faster
  24.  
  25. ## When should you refactor?
  26.  
  27. - First,`The rule of three`:three strikes of duplication.
  28. - Second,refactor when you add functionality.You can do it before or after adding the function.(Easier to add function or clean up the code after adding)
  29. - Third,do it when you need to fix a bug.
  30. - Last,refactor as you do a code review.
  31.  
  32. ## Still some problems...
  33.  
  34. - Database is not easy to be refactored.
  35. - Some refactorings may require the change of interfaces,which is not allowed for those which have been published.
  36. - Major design changes cannot be accomplished via refactoring.
  37.  
  38. ## Where to start?
  39.  
  40. *Look for "Bad smells" in code.*
  41.  
  42. ### Duplicated code
  43. Bad because if you modify one instance of duplicated code but not the others, you (may) have introduced a bug!(修改一个地方代码但是别的没改,可能引入错误)
  44.  
  45. ### Long Method
  46. Long methods are more difficult to understand
  47.  
  48. ### Large Class
  49. Large classes try to do too much, which reduces cohesion(上帝类,Activity类,职责太多)
  50.  
  51. ### Long Parameter List
  52. Hard to understand, can become inconsistent if the same parameter chain is being passed from method to method(参数过长的方法容易导致不一致性,想想starbucks项目的drawChart模块)
  53.  
  54. ### Divergent Change
  55. - Symptom: one type of change requires changing one subset of methods; another type of change requires changing another subset(一种原因修改代码中的一部分方法,另一种原因修改另一部分,则其实可以分成两个类)
  56. - Related to cohesion
  57.  
  58. ### Shotgun Surgery
  59. A change requires lots of little changes in a lot of different classes(导致大量不同类的大量小修改)
  60.  
  61. ### Feature Envy
  62. A method requires lots of information from some other class(倒不如一开始就给它,也就是将它移动到依赖的那个类中去)
  63.  
  64. ### Data Clumps
  65. Attributes that clump together (are used together) but are not part of the same class
  66.  
  67. ### Primitive Obsession
  68. characterized by a reluctance to use classes instead of primitive data types(使用太多的原始类型而不是类对象)
  69.  
  70. ### Switch Statements
  71. Switch statements are often duplicated in code; they can typically be replaced by use of polymorphism (let OO do your selection for you!)(使用多态替换switch)
  72.  
  73. ### Parallel Inheritance Hierarchies
  74. Similar to Shotgun Surgery; each time I add a subclass to one hierarchy, I need to do it for all related hierarchies
  75. Note: some design patterns encourage the creation of parallel inheritance hierarchies (比如工厂模式)
  76.  
  77. ### Lazy Class
  78. A class that no longer "pays its way"(留着是祸害,坏处大于好处)
  79.  
  80. ### Speculative Generality
  81. "Oh I think we need the ability to do this kind of thing someday"(预先设想的功能并没有发生)
  82.  
  83. ### Temporary Field
  84. An attribute of an object is only set/used in certain circumstances;
  85. but an object should need all of its attributes(为了特定需求而给类弄的一次性属性其实并不需要)
  86.  
  87. ### Message Chains
  88. A client asks an object A for another object B and then asks that object B for another object C etc. Bad because client depends on the structure of the navigation(绕圈子才能获得想要的东西就会使客户产生对导航结构的依赖)
  89.  
  90. ### Middle Man
  91. If a class is delegating more than half of its responsibilities to another class, do you really need it? Involves trade-offs, some design patterns encourage this (e.g. Decorator)(专门分派工作给别人做,自己却几乎不做什么)
  92.  
  93. ### Inappropriate Intimacy
  94. Pairs of classes that know too much about each other’s implementation details (loss of encapsulation; change one class, the other has to change)(一对类知道太多互相的实现细节)
  95.  
  96. ### Data Class (information holder)
  97. These are classes that have fields, getting and setting methods for the fields, and nothing else; they are data holders, but objects should be about data AND behavior(除了信息什么也没有,换句话说这个类没有行为,只是持有数据)
  98.  
  99. ### Refused Bequest
  100. A subclass ignores most of the functionality provided by its superclass
  101. Subclass may not pass the “IS-A” test(子类几乎不用父类继承下来的东西,这样实际不能成为继承关系)
  102.  
  103. ### Comments
  104. Comments are sometimes used to hide bad code(隐藏了臭味)
  105.  
  106. ## Introducing common methods to refactor
  107.  
  108. - Extract method
  109. - Replace Temp with Query
  110. - Move method
  111. - Replace Conditional with polymorphism
  112. - Introduce Null Object
  113. - Separate Query for Modifier
  114. - Introduce Parameter Object
  115. - Encapsulate Collection
  116. - Replace Nested Conditional with Guard Clauses
  117.  
  118. ### Extract method(方法抽取,隔离变化,针对接口编程)
  119. You have a code fragment that can be grouped together
  120. Turn the fragment into a method whose name explains the purpose of the fragment
  121.  
  122. ### Replace Temp with Query(使用函数调用代替临时变量)
  123. You are using a temporary variable to hold the result of an expression,
  124. Extract the expression into a method;
  125. Replace all references to the temp with the expression.
  126. The new method can then be used in other methods
  127.  
  128. ### Move method(高内聚,低耦合)
  129. A method is using more features (attributes and operations) of another class than the class on which it is defined(如果特性羡慕,那么移动到使用最多的属性和方法的类)
  130.  
  131. Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether
  132.  
  133. When moving a method to a new class, we examine its code to see if makes use of internal attributes of its original class
  134.  
  135. All such attributes become parameters to the method in its new home. (If the method already had parameters, the new parameters get tacked on to the end of its existing parameter list.)
  136.  
  137. ### Replace Conditional with polymorphism(封装的思想)
  138. You have a conditional that chooses different behavior depending on the type of an object
  139.  
  140. Move each "leg" of the conditional to an overriding method in a subclass.
  141. Make the original method abstract(子类实现不同的'条件')
  142.  
  143. ### Introduce Null Object(考虑封装成一个对象,而不是用一堆的null判断)
  144. Repeated checks for a null value
  145.  
  146. Rather than returning a null value , return an instance of a "null custom" object
  147.  
  148. ### Separate Query for Modifier(查询与修改分离)
  149. Sometimes you will encounter code that does something like this
  150. `getTotalOutstandingAndSetReadyForSummaries()`
  151.  
  152. It is a query method but it is also changing the state of the object being called
  153.  
  154. This change is known as a "side effect" because it’s not the primary purpose of the method
  155.  
  156. It is generally accepted practice that queries should not have side effects so this refactoring says to split methods like this into:
  157.  
  158. ```
  159. getTotalOutstanding()
  160. setReadyForSummaries()
  161. ```
  162.  
  163. Try as best as possible to avoid side effects in query methods
  164.  
  165. ### Introduce Parameter Object
  166. You have a group of parameters that go naturally together,stick them in an object and pass the object
  167.  
  168. Imagine methods like
  169. ```
  170. amountInvoicedIn(start: Date; end: Date);
  171. amountOverdueIn(start: Date; end: Date);
  172. ```
  173. This refactoring says replace them with something like
  174. `amountInvoicedIn(dateRange: DateRange)`
  175.  
  176. The new class starts out as a data holder but will likely attract methods to it
  177.  
  178. ### Encapsulate Collection(封装具体实现细节,提高效率,减少依赖性)
  179. A method returns a collection,make it return a read-only version of the collection and provide add/remove methods
  180.  
  181. ### Replace Nested Conditional with Guard Clauses
  182. This refactoring relates to the purpose of conditional code
  183.  
  184. One type of conditional checks for a variation in "normal" behavior
  185.  
  186. The other type of conditional checks for unusual circumstances that require special behavior;
  187.  
  188. if all of these checks fail then the system proceeds with "normal behavior"
  189.  
  190. With the refactoring, all of the code trying to identify special conditions are turned into one-line statements that determine whether the condition applies and if so handles it,that’s why these statements are called "guard clauses"
  191.  
  192. Sometimes complex compound conditionals can be converted into guard clauses by reversing the condition that is being tested,by reversing the conditionals and "failing early" you simplify the code(更早失败,简化代码)
Add Comment
Please, Sign In to add comment