Your SlideShare is downloading. ×
0
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Refactoring - improving the smell of your code
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Refactoring - improving the smell of your code

2,732

Published on

Published in: Technology, Design
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,732
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
45
Comments
0
Likes
0
Embeds 0
No embeds

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 <ul><ul><li>What is refactoring? </li></ul></ul><ul><ul><li>Why refactor? </li></ul></ul><ul><ul><li>When NOT to refactor? </li></ul></ul><ul><ul><li>When to refactor? </li></ul></ul><ul><ul><li>Code Smells </li></ul></ul><ul><ul><li>How to refactor? </li></ul></ul><ul><ul><li>Refactoring Tools </li></ul></ul>
  • 3. What is refactoring? <ul><ul><li>Disciplined  technique for restructuring existing code without changing its external behavior. </li></ul></ul><ul><ul><li>Series of small (measured in minutes) behavior preserving code transformations. </li></ul></ul>
  • 4. Why refactor? <ul><ul><li>To make code easier to work with in the future  </li></ul></ul><ul><ul><li>Speed up development </li></ul></ul><ul><ul><li>Code is written once but is read many times </li></ul></ul><ul><ul><li>Developers of all skill levels must be able to understand the code </li></ul></ul>
  • 5. Why refactor? <ul><ul><li>To improve design  </li></ul></ul><ul><ul><ul><li>Improve reusability and remove duplication </li></ul></ul></ul><ul><ul><ul><li>Allow for easier extensions and align code with functionality and usage </li></ul></ul></ul><ul><ul><ul><li>Reduce complexity </li></ul></ul></ul><ul><ul><li>Improving code quality and rigidity, reduce bugs </li></ul></ul><ul><ul><li>Simplify testing </li></ul></ul>
  • 6. Why refactor? <ul><ul><li>Dramatically reduce  development  cost and headaches </li></ul></ul>
  • 7. When NOT to refactor? <ul><ul><li>When it has no immediate business value </li></ul></ul><ul><ul><ul><li>Refactoring should be done as part of fixing a defect or adding new feature </li></ul></ul></ul><ul><ul><li>Code does not work </li></ul></ul><ul><ul><li>Inadequate test coverage </li></ul></ul><ul><ul><li>Breaking used interfaces </li></ul></ul><ul><ul><li>Requires expensive data migrations  </li></ul></ul><ul><ul><li>Tight deadline </li></ul></ul>
  • 8. When to refactor? <ul><ul><li>During defect fix or addition of a new feature </li></ul></ul><ul><ul><li>When code is hard to read and understand </li></ul></ul><ul><li>  </li></ul><ul><ul><li>When code requires complex unit tests </li></ul></ul><ul><li>  </li></ul><ul><ul><li>When upcoming changes are not easily supported by existing code </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Existing code requires a change every time new feature is added </li></ul></ul><ul><li>  </li></ul><ul><ul><li>As result of code reviews </li></ul></ul>
  • 9. How to refactor <ul><ul><li>Know your end goal </li></ul></ul><ul><ul><li>Add missing unit tests </li></ul></ul><ul><ul><li>Ensure unit tests pass before you start and in between each small refactoring </li></ul></ul><ul><ul><li>Small, incremental, purposeful commits   </li></ul></ul><ul><ul><li>Stop when you are unsure </li></ul></ul><ul><ul><li>Backtrack  </li></ul></ul><ul><ul><li>Pairing/Code Reviews </li></ul></ul>
  • 10. Refactoring and Design Patterns <ul><ul><li>Go hand in hand </li></ul></ul><ul><ul><li>Using patterns to improve existing design is better then using patterns in the new design </li></ul></ul><ul><ul><ul><li>  When designing new system, devs: </li></ul></ul></ul><ul><ul><ul><ul><li>Don't know all the requirements </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Don't have a full working application </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Guessing as to which patterns are actually applicable </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Tend to over-engineer </li></ul></ul></ul></ul>
  • 11. Code smell?  <ul><ul><li>Code smell is a possible symptom of the deeper problem </li></ul></ul><ul><li>Duplicate code </li></ul><ul><li>if ( isSpecialDeal ()) {   </li></ul><ul><li>      total = price * 0.95 ;   </li></ul><ul><li>      send();   </li></ul><ul><li>}  else {   </li></ul><ul><li>    total = price * 0.98 ;   </li></ul><ul><li>    send();   </li></ul><ul><li>} </li></ul><ul><li>Long and complicated methods/classes </li></ul><ul><li>public class PromotionFilterServiceImpl{ </li></ul><ul><li>    public LoyaltyProgramVO filter (... ...){ </li></ul><ul><li>        // 1 method, 2  nested loops,  13   if  statements,  80  lines of code =  1000+  lines test  class </li></ul><ul><li>     } </li></ul><ul><li>} </li></ul>
  • 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) <ul><li>Comments </li></ul><ul><li>class DistanceCalculator (){ </li></ul><ul><li>    // FIXME: rename this method   </li></ul><ul><li>    public int process(Coordinates coords){  </li></ul><ul><li>    //this method calculates the distance between 2 coordinates   </li></ul><ul><li>    ..... . </li></ul><ul><li>    ..... </li></ul><ul><li>    } </li></ul><ul><li>} </li></ul><ul><li>Cascading change </li></ul><ul><ul><li>Small change in 1 place cascades into multiple changes in other parts of the code </li></ul></ul>
  • 16. Refactoring Tools <ul><ul><li>IDE </li></ul></ul>
  • 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 <ul><li>Books: </li></ul><ul><ul><li>M Fowler - Refactoring: Improving the Design of Existing Code   </li></ul></ul><ul><ul><li>Gang Of Four - Design Patterns </li></ul></ul><ul><ul><li>Joshua Karievsky - Refactoring to Patterns </li></ul></ul><ul><li>Websites: </li></ul><ul><ul><li>refactoring.com </li></ul></ul><ul><ul><li>https://mwiki.points.com/wiki/SoftwareEngineering </li></ul></ul>

×