Fluent Refactoring (Lone Star Ruby Conf 2013)
-
Upload
sam-livingston-gray -
Category
Technology
-
view
1.178 -
download
3
description
Transcript of Fluent Refactoring (Lone Star Ruby Conf 2013)
![Page 1: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/1.jpg)
Fluent RefactoringSam Livingston-Gray
THERE WILL BE CODE!
It may bethis small
(1..100).each do |i| s = '' fizz = (i % 3).zero? buzz = (i % 5).zero? s << 'Fizz' if fizz s << 'Buzz' if buzz s << '!' if fizz || buzz s = i if s =~ /^$/ puts send
1
![Page 2: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/2.jpg)
Let’s Talk About Math!
2
![Page 3: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/3.jpg)
http://2012books.lardbucket.org/books/elementary-algebra/section_06/5d10b670d78abac93a4572dc0c2afb0f.jpg3
![Page 4: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/4.jpg)
http://www.wikihow.com/Image:Solve-for-X-Step-12.jpg4
![Page 5: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/5.jpg)
http://math.about.com/od/algebra/ss/birthday.htm5
![Page 6: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/6.jpg)
http://www.smosh.com/smosh-pit/photos/16-wonderfully-stupid-test-answers6
![Page 7: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/7.jpg)
Algebra
7
![Page 8: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/8.jpg)
Algebra Isn’t Math
8
![Page 9: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/9.jpg)
Algebra Isn’t all of Math
9
![Page 10: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/10.jpg)
Algebra ⊂ Math
Math
Algebra
10
![Page 11: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/11.jpg)
http://upload.wikimedia.org/wikipedia/commons/thumb/0/08/NautilusCutawayLogarithmicSpiral.jpg/793px-NautilusCutawayLogarithmicSpiral.jpg11
![Page 12: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/12.jpg)
http://upload.wikimedia.org/wikipedia/commons/a/a4/Mandelbrot_sequence_new.gif12
![Page 13: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/13.jpg)
http://mathequalslove.blogspot.com/2012/12/hexaflexagon-love.html13
![Page 14: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/14.jpg)
http://think-like-a-git.net/sections/graph-theory/seven-bridges-of-konigsberg.html14
![Page 15: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/15.jpg)
Math is a LanguageAlgebra is its Grammar
15
![Page 16: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/16.jpg)
Dick and Jane
16
![Page 17: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/17.jpg)
Fluent Refactoring
17
![Page 18: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/18.jpg)
http://www.kickasslabs.com/2012/04/28/rails-conf-2012-images/100_0304/
Can I get a definition?
18
![Page 19: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/19.jpg)
Flu·en·cy (noun)What you can say when you’renot thinking about how to say it
19
![Page 20: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/20.jpg)
What you can say when you’rewoken up in the middle of the night
with a flashlight in your face
Flu·en·cy (noun)
20
![Page 21: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/21.jpg)
http://dailyawesimity.files.wordpress.com/2013/01/cat-stress-relief-4.jpg
Stress
21
![Page 22: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/22.jpg)
http://www.jamesshore.com/Blog/Proficiencies-of-Planning.html
Level 1 Tarzan ata party
“Beer!”“Good party.”
Level 2 Going tothe party
"Where is the party?""How do I get to the party?"
Level 3 Discussingthe party
"What happened at the party last night?"
Level 4 Charlie Rose "Should parties be illegal?"
Levels of Proficiency
22
![Page 23: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/23.jpg)
Re·fac·tor·ing (noun)"...a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior."
-refactoring.com
23
![Page 24: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/24.jpg)
http://refactoring.com/
"...a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior."
24
![Page 25: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/25.jpg)
"Yeah, we're going to have to takea couple of weeks out of the schedule for refactoring, and that's probably going
to break some stuff."
Doin It Rong
25
![Page 26: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/26.jpg)
"Yeah, we're going to have to takea couple of weeks out of the schedule for refactoring, and that's probably going
to break some stuff."
Doin It Rong
26
![Page 27: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/27.jpg)
"Yeah, we're going to have to takea couple of weeks out of the schedule for refactoring, and that's probably going
to break some stuff."
Doin It Rong
27
![Page 28: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/28.jpg)
Re·fac·tor·ing (noun)"...a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior."
-refactoring.com
28
![Page 29: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/29.jpg)
http://refactoring.com/
"...a disciplined technique for restructuring an existing body of code, altering its internal structure
without changing its external behavior."
29
![Page 30: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/30.jpg)
Tests are implied.-Katrina Owen,
“Therapeutic Refactoring”
30
![Page 31: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/31.jpg)
Re·fac·tor·ing (noun)"...a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior."
-refactoring.com
31
![Page 32: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/32.jpg)
Re·fac·tor·ing (noun)"...a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior."
32
![Page 33: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/33.jpg)
Re·fac·tor·ing (noun)
A technique forrestructuring code
without changing behavior
33
![Page 34: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/34.jpg)
Re·fac·tor (verb)
To restructure codewithout changing behavior
34
![Page 35: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/35.jpg)
Tell a clearer storywith fewer details
35
![Page 36: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/36.jpg)
Re·fac·tor·ing (noun)
A language that describes ways to make your code
suck less.
36
![Page 37: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/37.jpg)
THESISES
37
![Page 38: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/38.jpg)
THESISESTHESES
38
![Page 39: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/39.jpg)
THESISESTHESESTHESII
39
![Page 40: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/40.jpg)
THESISESTHESESTHESII
MY POINT(S)
40
![Page 41: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/41.jpg)
You're probably already fluent in refactoring.
Level 1:Rename Variable; Rename Method.
41
![Page 42: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/42.jpg)
You can become more fluent in refactoring.
It just takes practice.
42
![Page 43: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/43.jpg)
Putting in the practice to become more fluent in refactoring is worth it.
Because you’ll be able to say more things when you’re under stress.
43
![Page 44: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/44.jpg)
Refactoring Session
44
![Page 45: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/45.jpg)
Used with:
• Permission
• Obfuscation
• Respect
Production Rails Code
45
![Page 46: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/46.jpg)
Schedule Cable Installs
46
![Page 47: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/47.jpg)
class InstallationsController < ActionController::Base # lots more stuff...
def schedule desired_date = params[:desired_date] if request.xhr? begin if @installation.pending_credit_check? render :json => {:errors => ["Cannot schedule installation while credit check is pending"]}, :status => 400 return end audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end end rescue ActiveRecord::RecordInvalid => e render :json => {:errors => [e.message] } rescue ArgumentError => e render :json => {:errors => ["Could not schedule installation. Start by making sure the desired date is on a business day."]} end else if @installation.pending_credit_check? flash[:error] = "Cannot schedule installation while credit check is pending" redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end end rescue => e flash[:error] = e.message end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end
# lots more stuff...end
47
![Page 48: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/48.jpg)
class InstallationsController < ActionController::Base # lots more stuff...
def schedule desired_date = params[:desired_date] if request.xhr? begin if @installation.pending_credit_check? render :json => {:errors => ["Cannot schedule installation while credit check is pending"]}, :status => 400 return end audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end end rescue ActiveRecord::RecordInvalid => e render :json => {:errors => [e.message] } rescue ArgumentError => e render :json => {:errors => ["Could not schedule installation. Start by making sure the desired date is on a business day."]} end else if @installation.pending_credit_check? flash[:error] = "Cannot schedule installation while credit check is pending" redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end end rescue => e flash[:error] = e.message end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end
# lots more stuff...end
Observations
~800 lines in file
~50 lines in method
Longest line: 177 chars
Indentation: 4-16 spaces
Nested control structures:
audit_trail_for
begin/rescue/end
if/else/end
48
![Page 49: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/49.jpg)
http://scientopia.org/blogs/whitecoatunderground/2009/06/10/my-head-just-asploded-twice/
Complexity
49
![Page 50: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/50.jpg)
http://shipitsquirrel.github.io/
Ship it!
50
![Page 51: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/51.jpg)
http://shipitsquirrel.github.io/
Ship Shit!
51
![Page 52: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/52.jpg)
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
~800 lines
52
![Page 53: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/53.jpg)
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
~800 lines
53
![Page 54: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/54.jpg)
Make the Job Smaller
54
![Page 55: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/55.jpg)
Replace Method with Method Object
55
![Page 56: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/56.jpg)
class InstallationsController < ActionController::Base def schedule # LOTS OF CODE endend
56
![Page 57: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/57.jpg)
class InstallationsController < ActionController::Base def schedule
endend
class ScheduleInstallation def call
endend
# LOTS OF CODE
57
![Page 58: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/58.jpg)
class InstallationsController < ActionController::Base def schedule
endend
class ScheduleInstallation def call
endend
# LOTS OF CODE
58
![Page 59: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/59.jpg)
class InstallationsController < ActionController::Base def schedule
endend
class ScheduleInstallation def call
endend
ScheduleInstallation.new.call
# LOTS OF CODE
59
![Page 60: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/60.jpg)
class ScheduleInstallation def call # LOTS OF CODE endend
60
![Page 61: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/61.jpg)
class ScheduleInstallation def initialize(controller) @controller = controller end
def call # LOTS OF CODE endend
61
![Page 62: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/62.jpg)
class ScheduleInstallation def initialize(controller) @controller = controller end
def call # LOTS OF CODE end
def method_missing(m, *a, &b) @controller.send(m, *a, &b) endend
62
![Page 63: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/63.jpg)
Code Archaeology
63
![Page 64: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/64.jpg)
if request.xhr? # ...20 lines...else # ...22 lines...end
64
![Page 65: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/65.jpg)
if request.xml_http_request? # ...20 lines...else # ...22 lines...end
65
![Page 66: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/66.jpg)
if request.xml_http_request? begin if @installation.pending_credit_check? render :json => #... return end #... endelse # ...22 lines...end
66
![Page 67: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/67.jpg)
if request.xhr? begin if @installation.pending_credit_check? render :json => #... return end #... endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin #...end
67
![Page 68: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/68.jpg)
if request.xhr? begin if @installation.pending_credit_check? render :json => #... return end #... endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin #...end
68
![Page 69: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/69.jpg)
if request.xhr? begin if @installation.pending_credit_check? render :json => #... return end #... endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin #...end
69
![Page 70: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/70.jpg)
if request.xhr? begin if @installation.pending_credit_check? render :json => #... return end #... endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to installations_path(:city_id => @installation.city_id, :view => "calendar") and return end begin #...end
70
![Page 71: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/71.jpg)
if request.xhr? begin if @installation.pending_credit_check? render :json => #... return end #... endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to installations_path(:city_id => return end begin #...end
if request.xhr? if @installation.pending_credit_check? render :json => #... return endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to(...) and return return endend
if request.xhr? #...else #...71
![Page 72: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/72.jpg)
if request.xhr? #...else #...end
if request.xhr? #...else #...end
ZOMGduplication!!!1!!
72
![Page 73: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/73.jpg)
if request.xhr? if @installation.pending_credit_check? #... endelse if @installation.pending_credit_check? #... endend
if request.xhr? #...else #...end
73
![Page 74: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/74.jpg)
Emphasis
74
![Page 75: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/75.jpg)
if request.xhr? if @installation.pending_credit_check? #... endelse if @installation.pending_credit_check? #... endend
75
![Page 76: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/76.jpg)
Flatten Nested Conditionals
source: Michael Feathers,writing for Dr. Dobbs
76
![Page 77: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/77.jpg)
if request.xhr? if @installation.pending_credit_check? render :json => #... return endelse if @installation.pending_credit_check? flash[:error] = #... redirect_to #... return endend
77
![Page 78: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/78.jpg)
if ajax if pending_credit_check render :json => #... return endelse if pending_credit_check flash[:error] = #... redirect_to #... return endend
78
![Page 79: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/79.jpg)
if ajax if pending_credit_check render :json => #... return endelse if pending_credit_check flash[:error] = #... redirect_to #... return endend
if ajax if pending_credit_check render :json => #... return endendif not ajax if pending_credit_check flash[:error] = #... redirect_to #... return endend
79
![Page 80: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/80.jpg)
if ajax if pending_credit_check render :json => #... return endendif not ajax if pending_credit_check flash[:error] = #... redirect_to #... return endend
if ajax && pending_credit_check render :json => #... returnendif (not ajax) && pending_credit_check flash[:error] = #... redirect_to #... returnend
80
![Page 81: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/81.jpg)
if ajax && pending_credit_check render :json => #... returnendif (not ajax) && pending_credit_check flash[:error] = #... redirect_to #... returnend
if pending_credit_check if ajax render :json => #... return end if not ajax flash[:error] = #... redirect_to #... return endend
81
![Page 82: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/82.jpg)
if pending_credit_check if ajax render :json => #... return end if not ajax flash[:error] = #... redirect_to #... return endend
if pending_credit_check if ajax render :json => #... return else flash[:error] = #... redirect_to #... return endend
82
![Page 83: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/83.jpg)
if pending_credit_check if ajax render :json => #... return else flash[:error] = #... redirect_to #... return endend
if pending_credit_check if ajax render :json => #... else flash[:error] = #... redirect_to #... end returnend
83
![Page 84: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/84.jpg)
if ajax if pending_credit_check render :json => #... return endelse if pending_credit_check flash[:error] = #... redirect_to #... return endend
if pending_credit_check if ajax render :json => #... else flash[:error] = #... redirect_to #... end returnend
84
![Page 85: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/85.jpg)
if pending_credit_check if ajax render :json => #... else flash[:error] = #... redirect_to #... end returnend
if pending_credit_check cant_schedule_while_credit_check_pending returnend
85
![Page 86: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/86.jpg)
Exception Handling
86
![Page 87: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/87.jpg)
raise “wtf” if coin.toss.heads?begin raise “wtf” if coin.toss.heads?end
87
![Page 88: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/88.jpg)
begin raise “wtf” if coin.toss.heads?end
begin raise “wtf” if coin.toss.heads?rescue => e raise eend
88
![Page 89: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/89.jpg)
begin raise “wtf” if coin.toss.heads?rescue => e raise eend
89
![Page 90: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/90.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue #... endrescue => e raise eend
90
![Page 91: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/91.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? end endrescue => e raise eend
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? end endrescue => e if request.xhr? raise e else raise e endend91
![Page 92: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/92.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? end endrescue => e if request.xhr? raise e else raise e endend
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? # DO NOTHING else raise “yak” if Moon.gibbous? end endrescue => e if request.xhr? raise “tfw” if tuesday? else raise e endend92
![Page 93: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/93.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? # DO NOTHING else raise “yak” if Moon.gibbous? end endrescue => e if request.xhr? raise “tfw” if tuesday? else raise e endend
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? # DO NOTHING else # DO NOTHING end endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend93
![Page 94: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/94.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue if request.xhr? # DO NOTHING else # DO NOTHING end endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
begin begin raise “wtf” if coin.toss.heads? rescue # DO NOTHING endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
94
![Page 95: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/95.jpg)
begin begin raise “wtf” if coin.toss.heads? rescue # DO NOTHING endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
begin begin raise “wtf” if coin.toss.heads? endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
95
![Page 96: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/96.jpg)
begin begin raise “wtf” if coin.toss.heads? endrescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
begin raise “wtf” if coin.toss.heads?rescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
96
![Page 97: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/97.jpg)
begin raise “wtf” if coin.toss.heads?rescue => e if request.xhr? raise “tfw” if tuesday? else raise “yak” if Moon.gibbous? endend
begin raise “wtf” if coin.toss.heads?rescue => e handle_exception(e)end
97
![Page 98: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/98.jpg)
Training Montage
98
![Page 99: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/99.jpg)
class ScheduleInstallation def call desired_date = params[:desired_date] if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin if request.xhr? audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end end else audit_trail_for(current_user) do if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end rescue Exception => e handle_exception e end endend
99
![Page 100: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/100.jpg)
class ScheduleInstallation def call desired_date = params[:desired_date] if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do if request.xhr? if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end else if @installation.schedule!(desired_date, :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end rescue Exception => e handle_exception e end endend
100
![Page 101: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/101.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do if request.xhr? if @installation.schedule!(params[:desired_date], :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end else if @installation.schedule!(params[:desired_date], :installation_type => params[:installation_type], :city => @city) if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end rescue Exception => e handle_exception e end endend
101
![Page 102: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/102.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if request.xhr? if success if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } end else if success if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end rescue Exception => e handle_exception e end endend
102
![Page 103: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/103.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if success if request.xhr? if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end else if request.xhr? render :json => {:errors => [%Q{Could not update installation. #{@installation.errors.full_messages.join(' ')}}] } else flash[:error] = %Q{Could not schedule installation, check the phase of the moon} redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end end end rescue Exception => e handle_exception e end endend
103
![Page 104: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/104.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if success if request.xhr? if @installation.scheduled_date date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} end else if @installation.scheduled_date if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end else scheduling_failed end end rescue Exception => e handle_exception e end endend
104
![Page 105: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/105.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if success if @installation.scheduled_date if request.xhr? date = @installation.scheduled_date.in_time_zone(@installation.city.timezone).to_date render :json => {:errors => nil, :html => schedule_response(@installation, date)} else if @installation.customer_provided_equipment? flash[:success] = %Q{Installation scheduled} else flash[:success] = %Q{Installation scheduled! Don't forget to order the equipment also.} end end end if request.xhr? # do nothing else redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end else scheduling_failed end end rescue Exception => e handle_exception e end endend
105
![Page 106: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/106.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if success if @installation.scheduled_date scheduling_succeeded end if request.xhr? # do nothing else redirect_to(@installation.customer_provided_equipment? ? customer_provided_installations_path : installations_path(:city_id => @installation.city_id, :view => "calendar")) end else scheduling_failed end end rescue Exception => e handle_exception e end endend
106
![Page 107: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/107.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do success = schedule! if success if @installation.scheduled_date scheduling_succeeded end do_post_success_cleanup else scheduling_failed end end rescue Exception => e handle_exception e end endend
107
![Page 108: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/108.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do if schedule! if @installation.scheduled_date scheduling_succeeded end do_post_success_cleanup else scheduling_failed end end rescue Exception => e handle_exception e end endend
108
![Page 109: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/109.jpg)
class ScheduleInstallation def call if @installation.pending_credit_check? cant_schedule_while_credit_check_pending return end
begin audit_trail_for(current_user) do if schedule! if @installation.scheduled_date scheduling_succeeded end do_post_success_cleanup else scheduling_failed end end rescue Exception => e handle_exception e end endend
request.xhr?
109
![Page 110: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/110.jpg)
Under The Rug
110
![Page 111: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/111.jpg)
class ScheduleInstallation def cannot_schedule_while_#... if request.xhr? # ...1 line... else # ...2 lines... end end
def handle_exception(e) if request.xhr? # ...7 lines... else # ...2 lines... end end
def scheduling_failed if request.xhr? # ...1 line... else # ...2 lines... end end
def scheduling_succeeded if request.xhr? # ...2 lines... else # ...5 lines... end end
def do_post_success_cleanup if request.xhr? # DO NOTHING else # ...1 line... end end
end
111
![Page 112: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/112.jpg)
class ScheduleInstallation private
def scheduling_failed if request.xhr? render :json => {:errors => [#... else flash[:error] = #... redirect_to #... end endend
112
![Page 113: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/113.jpg)
Single Responsibility Principle
113
![Page 114: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/114.jpg)
ScheduleInstallationScheduleInstallationAnd
DoOneThingForAJAXRequestsAndDoSomethingElseForHTMLRequests
114
![Page 115: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/115.jpg)
ScheduleInstallationScheduleInstallation And
DoOneThingForAJAXRequests AndDoSomethingElseForHTMLRequests
115
![Page 116: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/116.jpg)
“Methods, like classes, should have a single
responsibility.”-Sandi Metz
116
![Page 117: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/117.jpg)
http://en.wikipedia.org/wiki/File:Bill_%26_Ted%27s_Excellent_Adventure_(Original_Motion_Picture_Soundtrack).jpg117
![Page 118: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/118.jpg)
http://en.wikipedia.org/wiki/File:Paris_Tuileries_Garden_Facepalm_statue.jpg118
![Page 119: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/119.jpg)
Single Responsibility Principle
Every class should have a single responsibility, and that responsibility
should be entirely encapsulatedby the class.
119
![Page 120: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/120.jpg)
ScheduleInstallationScheduleInstallation And
DoOneThingForAJAXRequests AndDoSomethingElseForHTMLRequests
120
![Page 121: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/121.jpg)
Responder
121
![Page 122: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/122.jpg)
122
InstallationsController
![Page 123: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/123.jpg)
123
InstallationsController
ScheduleInstallation???
![Page 124: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/124.jpg)
124
InstallationsController
Responder
???
ScheduleInstallation???
![Page 125: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/125.jpg)
class ScheduleInstallation def call
private
def cannot_schedule_while_credit_check_pendin def handle_exception(e) def scheduling_failed def scheduling_succeeded def do_post_success_cleanupend
class Responderend
class ScheduleInstallation def callend
class Responder def cannot_schedule_while_credit_check_pe def handle_exception(e) def scheduling_failed def scheduling_succeeded def do_post_success_cleanupend
125
![Page 126: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/126.jpg)
126
Dualism
![Page 127: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/127.jpg)
class Responder def cannot_schedule_while_credit_check_pending # ...6 lines... end
def cannot_schedule_while_credit_check_pending if request.xhr? # ...1 line... else # ...2 lines... end end
def handle_exception(e) if request.xhr? # ...7 lines... else # ...2 lines... end end
def scheduling_failed if request.xhr? # ...1 line... else # ...2 lines... end end
def scheduling_succeeded if request.xhr? # ...2 lines... else # ...5 lines... end end
def do_post_success_cleanup if request.xhr? # NOP else # ...2 lines... end end end
![Page 128: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/128.jpg)
if request.xhr? # do fooelse # do barend
![Page 129: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/129.jpg)
Replace ConditionalWith Polymorphism
129
![Page 130: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/130.jpg)
class Responder def cannot_schedule_while_credit_check_pending def handle_exception(e) def scheduling_failed def scheduling_succeeded def do_post_success_cleanupend
class AJAXResponder def cannot_schedule_while_credit_check_pending def handle_exception(e) def scheduling_failed def scheduling_succeeded def do_post_success_cleanupend
class HTMLResponder def cannot_schedule_while_credit_check_pending def handle_exception(e) def scheduling_failed def scheduling_succeeded def do_post_success_cleanupend
![Page 131: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/131.jpg)
class AJAXResponder def scheduling_failed if request.xhr? render :json => #... else flash[:error] = #... redirect_to #... end endend
class HTMLResponder def scheduling_failed if request.xhr? render :json => #... else flash[:error] = #... redirect_to #... end endend
class AJAXResponder def scheduling_failed render :json => #... endend
class HTMLResponder def scheduling_failed flash[:error] = #... redirect_to #... endend
![Page 132: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/132.jpg)
132
InstallationsController
Responder
???
ScheduleInstallation???
![Page 133: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/133.jpg)
class InstallationsController < ActionController::Base
def schedule responder = if request.xhr? AJAXResponder.new(self) else HTMLResponder.new(self) end ScheduleInstallation.new(responder).call endend
![Page 134: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/134.jpg)
LESSONS LEARNED
134
![Page 135: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/135.jpg)
Refactoring is Math
135
![Page 136: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/136.jpg)
Fast CharacterizationTests Rock
136
![Page 137: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/137.jpg)
Embrace Duplicationif request.xhr?
137
0
2
4
6
8
10
![Page 138: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/138.jpg)
Embrace Evil Hacks
138
![Page 139: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/139.jpg)
Perspective MattersSuperficial design flaws
can concealfundamental design flaws
139
![Page 140: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/140.jpg)
http://gomakemeasandwich.wordpress.com/2011/10/26/a-yeaf-of-gmmas-where-do-we-go-from-here/
Where Do We Go From Here?
140
![Page 141: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/141.jpg)
141
![Page 142: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/142.jpg)
142
![Page 143: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/143.jpg)
143
![Page 145: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/145.jpg)
Practice!• Play with automated refactorings in an IDE
• Do them manually in the editor (wax on, wax off)
145
![Page 146: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/146.jpg)
Practice!• Commit early, commit often:
‘git reset --hard’ is your friend!
• Use throwaway branches
• Write fast characterization tests
146
![Page 147: Fluent Refactoring (Lone Star Ruby Conf 2013)](https://reader034.fdocuments.net/reader034/viewer/2022042814/554f9928b4c90586258b4711/html5/thumbnails/147.jpg)
Fluent Refactoringgithub.com/geeksam/fluent-refactoring
Twitter, Github: @geeksam
147