Refactoring

2,939 views
2,855 views

Published on

Talk at the Orlando Ruby User Group on January 2010 about Refactoring.

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

No Downloads
Views
Total views
2,939
On SlideShare
0
From Embeds
0
Number of Embeds
1,635
Actions
Shares
0
Downloads
50
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Refactoring

  1. 1. Refactoring { :from => :mess, :to => :clean_code, :through => :patterns } @caike Orlando Ruby User Group http://caikesouza.com January 2010 Friday, January 15, 2010
  2. 2. Agile Friday, January 15, 2010
  3. 3. Testing Friday, January 15, 2010
  4. 4. Patterns Friday, January 15, 2010
  5. 5. Professionalism Friday, January 15, 2010
  6. 6. Software Craftsmanship Friday, January 15, 2010
  7. 7. ? Friday, January 15, 2010
  8. 8. http://www.flickr.com/photos/eurleif/255241547/ Friday, January 15, 2010
  9. 9. "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler) Friday, January 15, 2010
  10. 10. “Free software only matters to those who can read” (Robert M. Lefkowitz) Friday, January 15, 2010
  11. 11. Friday, January 15, 2010
  12. 12. http://www.flickr.com/photos/dhammza/91435718/ Friday, January 15, 2010
  13. 13. Given messy code that works When I refactor Then it should be easier to understand And still work! Friday, January 15, 2010
  14. 14. Cleaning up the house Friday, January 15, 2010
  15. 15. http://www.flickr.com/photos/benfrantzdale/208672143/ http://www.flickr.com/photos/improveit/1574023621/ Friday, January 15, 2010
  16. 16. wiki, Fit, JUnit http://www.flickr.com/photos/benfrantzdale/208672143/ eXtreme Programming http://www.flickr.com/photos/improveit/1574023621/ Friday, January 15, 2010
  17. 17. Friday, January 15, 2010
  18. 18. http://www.flickr.com/photos/adewale_oshineye/2933030620 Friday, January 15, 2010
  19. 19. Some reasons... Friday, January 15, 2010
  20. 20. Design++ Friday, January 15, 2010
  21. 21. Money++ Friday, January 15, 2010
  22. 22. Respond to changes Money++ Friday, January 15, 2010
  23. 23. Respond to changes Money++ Release with confidence Friday, January 15, 2010
  24. 24. Effort-- Friday, January 15, 2010
  25. 25. Waterfall Jan Feb Mar Apr May Jun Jul Cost of Maintenance Extreme Programming Explained: Embrace Change Addison Wesley, 2000 Friday, January 15, 2010
  26. 26. XP Jan Feb Mar Apr May Jun Jul Cost of Maintenance Extreme Programming Explained: Embrace Change Addison Wesley, 2000 Friday, January 15, 2010
  27. 27. code LESS sleep MORE http://www.flickr.com/photos/x180/503574487/ Friday, January 15, 2010
  28. 28. http://www.flickr.com/photos/rockinrob/1485573200/ Friday, January 15, 2010
  29. 29. When ? Friday, January 15, 2010
  30. 30. When you add a function Friday, January 15, 2010
  31. 31. When you fix a bug Friday, January 15, 2010
  32. 32. Code Reviews Friday, January 15, 2010
  33. 33. http://www.flickr.com/photos/highwayoflife/2699887178/ Friday, January 15, 2010
  34. 34. Code Smells Friday, January 15, 2010
  35. 35. Duplicated Code Code Smells Friday, January 15, 2010
  36. 36. Duplicated Code Code Smells Long Method Friday, January 15, 2010
  37. 37. Duplicated Code Large Class Code Smells Long Method Friday, January 15, 2010
  38. 38. Duplicated Code Large Class Divergent Change Code Smells Long Method Friday, January 15, 2010
  39. 39. Duplicated Code Large Class Divergent Change Code Smells Long Parameter List Long Method Friday, January 15, 2010
  40. 40. Test Driven Development Friday, January 15, 2010
  41. 41. Red Green Refactor Friday, January 15, 2010
  42. 42. What if I Don’t ? Friday, January 15, 2010
  43. 43. Debt Metaphor Friday, January 15, 2010
  44. 44. http://www.flickr.com/photos/benfrantzdale/208672143/ Friday, January 15, 2010
  45. 45. http://www.flickr.com/photos/didmyself/3050138294/ Friday, January 15, 2010
  46. 46. Get ready for code! Friday, January 15, 2010
  47. 47. managers = [] employees.each do |e| managers << e if e.is_manager? end Saturday, January 16, 2010
  48. 48. managers = [] employees.each do |e| managers << e if e.is_manager? end Saturday, January 16, 2010
  49. 49. Replace Loop with Closure Method Saturday, January 16, 2010
  50. 50. managers = [] employees.each do |e| managers << e if e.is_manager? end Saturday, January 16, 2010
  51. 51. managers = employees. select { |e| e.is_manager? } Saturday, January 16, 2010
  52. 52. class Movie def initialize(stars) @stars = stars end def recommended? ((@stars > 5) ? 8 : 1) >= 8 end end Saturday, January 16, 2010
  53. 53. http://www.flickr.com/photos/anirudhkoul/3804552280/ Saturday, January 16, 2010
  54. 54. http://www.bartcop.com/marilyn-monroe001.jpg Saturday, January 16, 2010
  55. 55. http://thetorchonline.com/wp-content/uploads/2009/04/deathstar.jpg Saturday, January 16, 2010
  56. 56. class Movie def initialize(stars) @stars = stars end def recommended? ((@stars > 5) ? 8 : 1) >= 8 end end Saturday, January 16, 2010
  57. 57. Introduce Explaining Variable Saturday, January 16, 2010
  58. 58. class Movie def initialize(stars) @stars = stars end def recommended? ((@stars > 5) ? 8 : 1) >= 8 end end Saturday, January 16, 2010
  59. 59. class Movie def initialize(stars) @stars = stars end def recommended? rating = (@stars > 5) ? 8 : 1 rating >= 8 end end Saturday, January 16, 2010
  60. 60. class Movie def initialize(stars) @stars = stars end def recommended? rating = (@stars > 5) ? 8 : 1 rating >= 8 end end Saturday, January 16, 2010
  61. 61. Replace Temp With Query Saturday, January 16, 2010
  62. 62. class Movie def initialize(stars) @stars = stars end def recommended? rating = (@stars > 5) ? 8 : 1 rating >= 8 end end Saturday, January 16, 2010
  63. 63. class Movie def initialize(stars) @stars = stars end def recommended? rating >= 8 end def rating (@stars > 5) ? 8 : 1 end end Saturday, January 16, 2010
  64. 64. OMG, This is sooooo cooooool! Saturday, January 16, 2010
  65. 65. class Movie def recommended? rating >= 8 end def rating (@stars > 5) ? 8 : 1 end end Saturday, January 16, 2010
  66. 66. class Movie def recommended? rating >= 8 end def rating more_than_five_stars? ? 8 : 1 end def more_than_five_stars? @stars > 5 end end Saturday, January 16, 2010
  67. 67. Inline Method Saturday, January 16, 2010
  68. 68. class Movie def initialize...end def recommended? rating >= 8 end def rating more_than_five_stars? ? 8 : 1 end def more_than_five_stars? @stars > 5 end end Saturday, January 16, 2010
  69. 69. class Movie def initialize...end def recommended? rating >= 8 end def rating @stars > 5 ? 8 : 1 end end Saturday, January 16, 2010
  70. 70. mock = mock('user') expectation = mock.expects(:find) expectation.with("1") expectation.returns([]) Saturday, January 16, 2010
  71. 71. mock = mock('user') expectation = mock.expects(:find) expectation.with("1") expectation.returns([]) Saturday, January 16, 2010
  72. 72. Replace Temp With Chain Saturday, January 16, 2010
  73. 73. mock = mock('user') expectation = mock.expects(:find) expectation.with("1") expectation.returns([]) Saturday, January 16, 2010
  74. 74. mock = mock('user') mock.expects(:find).with("1"). returns([]) Saturday, January 16, 2010
  75. 75. def expects ... self end def with ... self end def returns ... self end Saturday, January 16, 2010
  76. 76. def charge(amount, ccnumber) begin conn = CC_Charger_Server.connect(...) conn.send(amount, ccnumber) rescue IOError => e Logger.log "Error: #{e}" return nil ensure conn.close end end Saturday, January 16, 2010
  77. 77. def charge(amount, ccnumber) begin conn = CC_Charger_Server.connect(...) conn.send(amount, ccnumber) rescue IOError => e Logger.log "Error: #{e}" return nil ensure conn.close end end Saturday, January 16, 2010
  78. 78. Extract Surrounding Method Saturday, January 16, 2010
  79. 79. def charge(amount, ccnumber) begin conn = CC_Charger_Server.connect(...) conn.send(amount, ccnumber) rescue IOError => e Logger.log "Error: #{e}" return nil ensure conn.close end end Saturday, January 16, 2010
  80. 80. def charge(amount, ccnumber) connect do |conn| conn.send(amount, ccnumber) end end Saturday, January 16, 2010
  81. 81. def connect begin conn = CC_Charger_Server.connect(...) yield conn rescue IOError => e Logger.log "Error: #{e}" return nil ensure conn.close end end Saturday, January 16, 2010
  82. 82. def body_fat_percentage(name, age, height, weight, metric_system) ... end Saturday, January 16, 2010
  83. 83. body_fat_percentage("fred", 30, 1.82, 90, 1) body_fat_percentage("joe", 32, 6, 220, 2) Saturday, January 16, 2010
  84. 84. body_fat_percentage("fred", 30, 1.82, 90, 1) body_fat_percentage("joe", 32, 6, 220, 2) Saturday, January 16, 2010
  85. 85. Introduce Named Parameter Saturday, January 16, 2010
  86. 86. def body_fat_percentage(name, age, height, weight, metric_system) ... end Saturday, January 16, 2010
  87. 87. def body_fat_percentage(name, params={}) # params[:age] # params[:height] # params[:weight] # params[:metric_system] end Saturday, January 16, 2010
  88. 88. body_fat_percentage("fred", 30, 1.82, 90, 1) body_fat_percentage("joe", 32, 6, 220, 2) Saturday, January 16, 2010
  89. 89. body_fat_percentage("fred", :age => 30, :height => 1.82, :weight => 90, MetricSystem::METERS_KG) body_fat_percentage("joe", :age => 32, :height => 6, :weight => 220, MetricSystem::FEET_LB) Saturday, January 16, 2010
  90. 90. user.posts.paginate(:page => params[:page], :per_page => params[:per_page] || 15) Saturday, January 16, 2010
  91. 91. user.posts.paginate(:page => params[:page], :per_page => params[:per_page] || 15) Saturday, January 16, 2010
  92. 92. Replace Magic Number with Symbolic Constant Saturday, January 16, 2010
  93. 93. user.posts.paginate(:page => params[:page], :per_page => params[:per_page] || 15) Saturday, January 16, 2010
  94. 94. CONTACTS_PER_PAGE = 15 user.posts.paginate(:page => params[:page], :per_page => params[:per_page] || CONTACTS_PER_PAGE) Saturday, January 16, 2010
  95. 95. class MountainBike def price ... end end MountainBike.new(:type => :rigid, ...) MountainBike.new(:type => :front_suspension, ...) MountainBike.new(:type => :full_suspension, ...) Saturday, January 16, 2010
  96. 96. def price if @type_code == :rigid (1 + @comission) * @base_price end if @type_code == :font_suspension (1 + @comission) * @base_price + @front_suspension_price end if @type_code == :full_suspension (1 + @comission) * @base_price+ @front_suspension_price + @rear_suspension_price end end Saturday, January 16, 2010
  97. 97. def price if @type_code == :rigid (1 + @comission) * @base_price end if @type_code == :font_suspension (1 + @comission) * @base_price + @front_suspension_price end if @type_code == :full_suspension (1 + @comission) * @base_price+ @front_suspension_price + @rear_suspension_price end if @type_code == :ultra_suspension ... end end Saturday, January 16, 2010
  98. 98. Saturday, January 16, 2010
  99. 99. Replace Conditional With Polymorphism Saturday, January 16, 2010
  100. 100. class MountainBike def price ... end end Saturday, January 16, 2010
  101. 101. module MountainBike def price ... end end Saturday, January 16, 2010
  102. 102. class RigidMountainBike include MountainBike end class FrontSuspensionMountainBike include MountainBike end class FullSuspensionMountainBike include MountainBike end Saturday, January 16, 2010
  103. 103. RigidMountainBike.new(:type => :rigid, ...) FrontSuspensionMountainBike.new(:type => :front_suspension, ...) FullSuspensionMountainBike.new(:type => :full_suspension, ...) Saturday, January 16, 2010
  104. 104. class RigidMountainBike include MountainBike def price (1 + @comission) * @base_price end end Saturday, January 16, 2010
  105. 105. def price if @type_code == :rigid raise "should not be called" end if @type_code == :font_suspension (1 + @comission) * @base_price + @front_suspension_price end if @type_code == :full_suspension (1 + @comission) * @base_price+ @front_suspension_price + @rear_suspension_price end end Saturday, January 16, 2010
  106. 106. class FrontSuspensionMountainBike include MountainBike def price (1 + @comission) * @base_price + @front_suspension_price end end class FullSuspensionMountainBike include MountainBike def price (1 + @comission) * @base_price + @front_suspension_price + @rear_suspension_price end end Saturday, January 16, 2010
  107. 107. def price if @type_code == :rigid raise "should not be called" end if @type_code == :font_suspension raise "should not be called" end if @type_code == :full_suspension raise "should not be called" end end Saturday, January 16, 2010
  108. 108. def price if @type_code == :rigid raise "should not be called" end if @type_code == :font_suspension raise "should not be called" end if @type_code == :full_suspension raise "should not be called" end end Saturday, January 16, 2010
  109. 109. class RigidMountainBike include MountainBike end class FrontSuspensionMountainBike include MountainBike end class FullSuspensionMountainBike include MountainBike end Saturday, January 16, 2010
  110. 110. Only the beginning... Saturday, January 16, 2010
  111. 111. Coding Dojo http://www.flickr.com/photos/el_ser_lomo/3267627038/ http://orlandodojo.wordpress.com/ http://groups.google.com/group/orlando-dojo/ Saturday, January 16, 2010
  112. 112. Saturday, January 16, 2010
  113. 113. Thank you! @caike http://caikesouza.com Saturday, January 16, 2010

×