Presentation is loading. Please wait.

Presentation is loading. Please wait.

Refactoring. Agile Coding Principles Collective Code Ownership in practice:  We cannot check in our code until: All tests are green. All duplication.

Similar presentations


Presentation on theme: "Refactoring. Agile Coding Principles Collective Code Ownership in practice:  We cannot check in our code until: All tests are green. All duplication."— Presentation transcript:

1 Refactoring

2 Agile Coding Principles Collective Code Ownership in practice:  We cannot check in our code until: All tests are green. All duplication has been removed The code is as expressive as we can make it. The code is as simple as we can make it.  Note: nothing in here says you wrote the original code! The “code is the documentation”  Comments should be minimized They often lie. They are an admission that we could not make our code express our ideas. There are many things you can do to make software expressive.

3 Refactoring Refactoring is the act of rewriting existing code to make it simpler and more efficient. XP refactorsmercilessly. Refactoring is aided by relentlesstesting and continuous integration. Refactoring takes courage! Refactoring aids in upgrading the design.  A goal of refactoring is to move toward a design pattern If design is good, then everybody will do it everyday! Adapted from presentation by J.Turpin & J.Morris, 2002 "No matter how far you have gone on the wrong road, turn back.” -- Turkish proverb

4 Code Smells Duplicate code Switch statements Long method Large class Data class (“data bag”) Long parameter list Primitive obsession Temporary field etc. Adapted from presentation by W..Wake, 2000 “If it stinks, change it.” Types of smells: Within classes: Smells within the structure and responsibilities of a single class Between classes: Smells arising from the structure and collaborations of many classes Examples:

5 Smells Within Classes Comments  typically don’t need inline comments  if comment describes a block of code, make it a method  Comment should not be more descriptive than method name - rename Long Method  Extract blocks into different methods produce a unique result callable from multiple locations someone else (client) might be interested in intermediate value  Just plain clean up the code  But, maybe we just need this really long method

6 Smells Within Classes Large Class  Keep adding one more thing to the class  Cohesion measure should be elevated if the class bloat obfuscates a singular responsibility.  Extract a new class - find features that reflect unique concept and delegate responsibility to the new class  Example: javax.swing.JTable - extract Column class (CRUD, margin) Cell class Long Parameter List  Grows occasionally with new parameters  Preserve object - pass the entire object instead of a single value  Introduce parameter object - combine parameters into a new (immutable) object

7 Smells Within Classes Type Embedded in Name  We have duplicate - argument type and method name duplicate one another  e.g. “addCourse(Course)” - bit of a style issue Uncommunicative Name  Example: 1 or 2 character names, even loop variables  Numbered names - side1, side2 vs. leftSide, rightSide  Abbreviations - some common idioms, though some (msg, conn, rs, i, etc.) are OK if used by convention Dead Code  Unused variables  Methods - OK if application-independent methods  Classes - OK if domain-independent classes

8 Smells Within Classes Speculative Generality  Guessing that flexibility will be need in future depends on what part system - lower level is probably OK (framework)  Remove general code, method, class, etc.  OK when a framework or testing/debugging code Magic Number  Constants in code - always make a named constant  Example: Math.PI instead of 3.14159 everywhere  Important subscripts in arrays/lists Complicated Expressions  Introduce intermediate (explaining) variables  Put expression into one or more methods

9 Smells Within Classes Duplicate Code  Can be nearly identical or conceptually identical  If inside same class, extract common code into private method  If unrelated classes, extract into one class or a new class Null Check  Using null or 0 as reasonable default value - OK by me!  Isolate check into single place and call externally and *internally*:  if (elements == null &&elements.size() == 0)

10 Smells Between Classes Data Class  Ensure methods arebehaviors, not view of internal structure  Class will have methods that return state information  Use accessors instead of public attributes  Remove setters  Hide collection attributes - Set getKeys() – see OK to me!  Examine clients for pattern of use Example: client should call area() instead of length()/width() Data Clump  Same data in classes or parameter lists (city, state, zip)  Or, same data and methods commonly appear  Extract common data/methods into new Class  Introduce a parameter object if commonality is in method

11 Smells Between Classes Primitive Obsession  Not enough objects - only primitive information  Combine related primitives into objects (Data Clump) Feature Envy  Class manipulating data of other class rather than its own  Place actions of method in appropriate place - the class and hide the data

12 Smells Between Classes Message Chains  a.b().c().d()  Issue is A knows too much about B and C, that they are delegating to  Extract method to out class in chain (e.g. add d() to class B) Middle Man  f() {delegate.f()}  Result from solving Message Chain above what! make up your mind!

13 Smells Between Classes Divergent Change  Class picks up unrelated features over time Should show up in your cohesion numbers  Extract related features to new class(es) Shotgun Surgery  Simple changes require modification to several classes Too much coupling To me, this is as much a smell as a refactoring practice  Isolate changes to common place (if possible) may need to extract changes to a new class and move features to it

14 Refactorings Fowler’s book has a catalog (see Readings (1)) There are many more Often reversible Principles: Pay attention to the mechanics Let the compiler tell you Small steps with constant tests (XP philosophy) Unit Testing and Refactoring  By having unit tests available, you can verify a refactoring produces functional equivalence  XP’s approach is “test-code-refactor” (“lather-rinse- repeat”) Adapted from presentation by W..Wake, 2000

15 Refactoring Refactoring actions rewrite source code  Within a single Java source file  Across multiple interrelated Java source files Refactoring actions preserve program semantics  Does not alter what program does, just affects the way it does it Refactoring strengths  Encourages exploratory programming  Facilitates Agile programming techniques  Encourages higher code quality  The resulting code should be of higher quality This should be represented in your static analysis tools

16 Refactor: Extract Method Observation: "You have a code fragment that can be grouped together (i.e. it is a cohesive 'lump' of code)." Refactoring:  Make a method whose name explains the fragment’s purpose.  Replace all occurrences of the fragment with calls to the method. Before: void printOwing() { printBanner(); System.out.println("name: " + name); System.out.println("amount: " + getOutstanding()); } After: void printOwing() { printBanner(); printDetails(getOutstanding()); } void printDetails (double outstanding) { System.out.println("name: " + name); System.out.println("amount: " + outstanding); } Adapted from Scach, Object-oriented and Classical Software Engineering

17 Refactor: Encapsulate Field Adapted from Scach, Object-oriented and Classical Software Engineering Adapted from presentation by W..Wake, 2000 Observation: "There is a public field." (1)Make the field private. (2)Create accessor method. (3)Create mutator method (only if needed.) (4)Revise all references to the field to call the accessor or mutator instead.

18 Introduce Null Object Use when your code does repeated checks for null return values  Null subclass type encapsulates default behaviors you might have when null is returned. Adapted from presentation by W..Wake, 2000

19 Parameterize Method Several methods on a class may do similar things but with different values in the method body  Create one method that uses a parameter for the different values  Useful when a small number of finite alternatives are used in a switch statement with constants (e.g. factory) HTTPService handleGet(…) handlePut(…) handle(serviceType,…) Adapted from presentation by W..Wake, 2000

20 Replace Constructor w/ Factory Method You want to do more than simply constructing an object when it is created You want to manage object lifecycles  Use a factory method/pattern  Replace the constructor with a factory method Adapted from presentation by W..Wake, 2000

21 Refactoring: Chain Constructors Observation: "There is a class with multiple constructors, each of which does non-trivial and partially overlapping work." Refactoring: (1)Identify and write the 'least common denominator' constructor. (2)Recode all other constructors to call this one to do the shared work. Adapted from Scach, Object-oriented and Classical Software Engineering

22 Refactoring: Split Loop BEFORE: void printValues() { double averageAge = 0; double totalSalary = 0; for (int i=0; i<people.length; i++) { averageAge += people[i].age; totalSalary += people[i].salary; } averageAge = averageAge / people.length; System.out.println(averageAge); System.out.println(totalSalary); } AFTER: void printValues() { double totalSalary = 0.0; for (int i=0; i<people.length; i++) totalSalary += people[i].salary; double averageAge = 0.0; for (int i=0; i<people.length; i++) averageAge += people[i].age; averageAge = averageAge / people.length; System.out.println(averageAge); System.out.println(totalSalary); } Observation: "There is a loop that is doing two things." (e.g., accumulating both average age and total salary for all employees.) Refactoring: Split into 2 loops.  Makes each thing easier to understand.  Opens the door to further refactoring/optimization (e.g., one loop may be replaced by a Collection aggregate function). Adapted from Scach, Object-oriented and Classical Software Engineering

23 Refactoring -- Parameterize Method Observation: "Several methods do similar things, but with different values in the method body." Refactoring: (1)Create a parameterized method that can substitute for each repetitive method; (2)Compile; (3)Replace the body of one method with a call to the new method; (4)Compile and test; (5)Replace all calls to old method with parameterized calls to new method; (6)Repeat 2--6 for all replaced methods. Nowadays you may be able to apply a generic Adapted from Scach, Object-oriented and Classical Software Engineering

24 Refactoring: Split Temporary Variable Observation: "You have a temporary variable assigned to in more than one place, but is not a loop variable nor an accumulating/collecting temporary variable." Refactoring: Make a separate temp var for each assignment. Before: double temp = 2 * (height + width); System.out.println(temp); temp = height * width; System.out.println(temp); After: final double perimeter = 2 * (height + width); System.out.println(perimeter); final double area = height * width; System.out.println(area); Adapted from Scach, Object-oriented and Classical Software Engineering

25 Refactoring Summary Refactoring is sometimes thought of as “in-place design”, or “just-in-time design”  I do not agree with these statements. Refactoring may improve the low-level design of code, but in places where full design is needed, do it! Refactoring is an expression of the Collective Code Ownership and Courage agile values  The code is the responsibility of everyone  You should not go into a code module, look at it and think “geez what a mess” and not do anything about it!  You also need the courage to alter schedule expectations in the name of quality Refactoring is only of limited use in isolation  Real power is in embedding in a test-code-test-code cycle  Use unit tests and metrics to diagnose, measure, and inject quality! 25

26 Readings 1.Fowler, M. Refactoring: Improving the Design of Existing Code, Addison-Wesley, 2000. 2.Wake, W. Refactoring Workbook, Addison-Wesley, 2003. 3.Kerievsky, J. Refactoring to Patterns, Addison-Wesley, 2005. 4.Scach, S. Classical and Object-oriented Software Engineering, 4 th ed., McGraw-Hill, 1999. ASU’s Safari online service has (1), which includes the full catalog of smells and refactorings Most XP books include a description of refactoring and its role in Agile development Websites: www.refactoring.com, www.xp123.comwww.refactoring.comwww.xp123.com There is a decent section in Code Complete 2


Download ppt "Refactoring. Agile Coding Principles Collective Code Ownership in practice:  We cannot check in our code until: All tests are green. All duplication."

Similar presentations


Ads by Google