Refactoring - improving the smell of your code
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
3,047
On Slideshare
1,898
From Embeds
1,149
Number of Embeds
3

Actions

Shares
Downloads
36
Comments
0
Likes
0

Embeds 1,149

http://lifeatpoints.com 1,143
http://lifeatpoints.com. 5
https://www.linkedin.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Refactoring - Improving the smell of your code Vlad Mandrychenko October 2011
  • 2. Agenda
      • What is refactoring?
      • Why refactor?
      • When NOT to refactor?
      • When to refactor?
      • Code Smells
      • How to refactor?
      • Refactoring Tools
  • 3. What is refactoring?
      • Disciplined  technique for restructuring existing code without changing its external behavior.
      • Series of small (measured in minutes) behavior preserving code transformations.
  • 4. Why refactor?
      • To make code easier to work with in the future 
      • Speed up development
      • Code is written once but is read many times
      • Developers of all skill levels must be able to understand the code
  • 5. Why refactor?
      • To improve design 
        • Improve reusability and remove duplication
        • Allow for easier extensions and align code with functionality and usage
        • Reduce complexity
      • Improving code quality and rigidity, reduce bugs
      • Simplify testing
  • 6. Why refactor?
      • Dramatically reduce  development  cost and headaches
  • 7. When NOT to refactor?
      • When it has no immediate business value
        • Refactoring should be done as part of fixing a defect or adding new feature
      • Code does not work
      • Inadequate test coverage
      • Breaking used interfaces
      • Requires expensive data migrations 
      • Tight deadline
  • 8. When to refactor?
      • During defect fix or addition of a new feature
      • When code is hard to read and understand
    •  
      • When code requires complex unit tests
    •  
      • When upcoming changes are not easily supported by existing code
    •  
      • Existing code requires a change every time new feature is added
    •  
      • As result of code reviews
  • 9. How to refactor
      • Know your end goal
      • Add missing unit tests
      • Ensure unit tests pass before you start and in between each small refactoring
      • Small, incremental, purposeful commits  
      • Stop when you are unsure
      • Backtrack 
      • Pairing/Code Reviews
  • 10. Refactoring and Design Patterns
      • Go hand in hand
      • Using patterns to improve existing design is better then using patterns in the new design
        •   When designing new system, devs:
          • Don't know all the requirements
          • Don't have a full working application
          • Guessing as to which patterns are actually applicable
          • Tend to over-engineer
  • 11. Code smell? 
      • Code smell is a possible symptom of the deeper problem
    • Duplicate code
    • if ( isSpecialDeal ()) {  
    •       total = price * 0.95 ;  
    •       send();  
    • }  else {  
    •     total = price * 0.98 ;  
    •     send();  
    • }
    • Long and complicated methods/classes
    • public class PromotionFilterServiceImpl{
    •     public LoyaltyProgramVO filter (... ...){
    •         // 1 method, 2  nested loops,  13   if  statements,  80  lines of code =  1000+  lines test  class
    •      }
    • }
  • 12. Code smell?  Too many method params     public void calculate ( int from , int to , int x , int y , int ... ){} Ungrouped related fields class DayCalculator  {     private Date to;       private  Date from;     private boolean skipSaturday;      private boolean skipSunday;         .....   } God classes class  ManagerServiceHelperImpl  {       public BigInt calculatePrice () {           //calculate stuff       }        public void handleResponse (){         //handle stuff       }       public Report manageReportPrinter (){          // manage stuff       }        public boolean isCanDoEverything ()     {           return true;     } }
  • 13. Code smell?  Unused/temporary object fields public class SessionVO {       private PartnerFeatureVO partnerFeatureVO = null ;     private ReserveCertificateVO reserveCertificateVO; // only used for claim       private boolean giftOrTransfer;     ......     ......    } Complicated VOs and Data Classes public class Session VO {     // contains 20 different nested mutable objects       // contains over 100 variables     // unknown lifecycle }
  • 14. Code smells (cont'd) Numerous switch/if/else statements     public double calculateArea ( Object shape )   {         double area = 0 ;         if (shape instanceof Square) {             Square square = ( Square ) shape ;             area = square. getA () * square. getA () ;          } else if (shape instanceof Rectangle) {            Rectangle rectangle = ( Rectangle ) shape ;             area = rectangle. getA () * rectangle. getB () ; }         } else if (shape instanceof Circle) {             Circle circle = ( Circle ) shape ;             area = Math . PI * cirle. getR () * cirle. getR () ;         }       return area ;       } Deep method chains     getHelper(){         getHandlerHelper(){             handleResponse(){               processReport();{               }             }         }     }
  • 15. Code smells (cont'd)
    • Comments
    • class DistanceCalculator (){
    •     // FIXME: rename this method  
    •     public int process(Coordinates coords){ 
    •     //this method calculates the distance between 2 coordinates  
    •     ..... .
    •     .....
    •     }
    • }
    • Cascading change
      • Small change in 1 place cascades into multiple changes in other parts of the code
  • 16. Refactoring Tools
      • IDE
  • 17. How to refactor: catalog of techniques http://refactoring.com/catalog/index.html  
  • 18. How to refactor: some techniques Rename Method class DistanceCalculator (){     // FIXME: rename this method       public int process(Coordinates coords){      //this method calculates the distance between 2 coordinates       ..... .     .....     } } class DistanceCalculator (){     public int calculateDistance(Coordinates coords){      ..... .     .....     } }
  • 19. How to refactor: some techniques Extract Interface class Employee (){     double getRate(){ ... }     boolean hasSpecialSkill(){ ... }     getName (){ ... }     getDepartment(){ ... }     } interface Billable{     double getRate();     boolean hasSpecialSkill(); } class Employee implements Billable() {} class Contractor implements Billable() {} 
  • 20. How to refactor: some techniques Introduce Parameter Object     public   void  calculate ( int   from ,  int   to ,  int   x ,  int   y ){ ... }     public   void  calculate ( Range range ,  Location location ){ ... }
  • 21. How to refactor: some techniques Replace Conditional with Polymorphism public class Client {          public   double  calculateArea ( Object  shape )   {         double  area  =   0 ;         if  (shape  instanceof  Square) {             Square square  =   ( Square )  shape ;             area  =  square. getA ()   *  square. getA () ;          }  else   if  (shape  instanceof  Rectangle) {            Rectangle  rectangle  =   ( Rectangle )  shape ;             area  =  rectangle. getA ()   *  rectangle. getB () ;   }         } else   if  (shape  instanceof  Circle) {             Circle circle  =   ( Circle )  shape ;             area  =   Math . PI   *  cirle. getR ()   *  cirle. getR () ;         }       return  area ;        } } public class Square implements Shape   {     private double a ;      ...          public double getArea ()   {        return a * a ;       } } public class Rectangle implements Shape {     private double a;     private double b;     ...     public double getArea () {       return a * b;     } } public class Client {     private Shape shape;     ...     public double calculateArea() {       return shape.getArea();     } }
  • 22. How to refactor: some techniques Replace Type Code with State/Strategy
  • 23. How to refactor: some techniques Replace Inheritance with Delegation
  • 24. Reference Material
    • Books:
      • M Fowler - Refactoring: Improving the Design of Existing Code  
      • Gang Of Four - Design Patterns
      • Joshua Karievsky - Refactoring to Patterns
    • Websites:
      • refactoring.com
      • https://mwiki.points.com/wiki/SoftwareEngineering