SlideShare una empresa de Scribd logo
1 de 147
Descargar para leer sin conexión
Fluent Refactoring
Sam Livingston-Gray
THERE
WILL BE
CODE!
It may be
this 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 s
end
1
Let’s Talk About Math!
2
http://2012books.lardbucket.org/books/elementary-algebra/section_06/5d10b670d78abac93a4572dc0c2afb0f.jpg
3
http://www.wikihow.com/Image:Solve-for-X-Step-12.jpg
4
http://math.about.com/od/algebra/ss/birthday.htm
5
http://www.smosh.com/smosh-pit/photos/16-wonderfully-stupid-test-answers
6
Algebra
7
Algebra Isn’t Math
8
Algebra Isn’t all of Math
9
Algebra ⊂ Math
Math
Algebra
10
http://upload.wikimedia.org/wikipedia/commons/thumb/0/08/NautilusCutawayLogarithmicSpiral.jpg/793px-NautilusCutawayLogarithmicSpiral.jpg
11
http://upload.wikimedia.org/wikipedia/commons/a/a4/Mandelbrot_sequence_new.gif
12
http://mathequalslove.blogspot.com/2012/12/hexaflexagon-love.html
13
http://think-like-a-git.net/sections/graph-theory/seven-bridges-of-konigsberg.html
14
Math is a Language
Algebra is its Grammar
15
Dick and Jane
16
Fluent Refactoring
17
http://www.kickasslabs.com/2012/04/28/rails-conf-2012-images/100_0304/
Can I get a
definition?
18
Flu·en·cy (noun)
What you can say when you’re
not thinking about how to say it
19
What you can say when you’re
woken up in the middle of the night
with a flashlight in your face
Flu·en·cy (noun)
20
http://dailyawesimity.files.wordpress.com/2013/01/cat-stress-relief-4.jpg
Stress
21
http://www.jamesshore.com/Blog/Proficiencies-of-Planning.html
Level 1
Tarzan at
a party
“Beer!”
“Good party.”
Level 2
Going to
the party
"Where is the party?"
"How do I get to the party?"
Level 3
Discussing
the party
"What happened at the party
last night?"
Level 4 Charlie Rose "Should parties be illegal?"
Levels of Proficiency
22
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
http://refactoring.com/
"...a disciplined
technique for restructuring an existing
body of code, altering its internal
structure without changing its external
behavior."
24
"Yeah, we're going to have to take
a couple of weeks out of the schedule
for refactoring, and that's probably going
to break some stuff."
Doin It Rong
25
"Yeah, we're going to have to take
a couple of weeks out of the schedule
for refactoring, and that's probably going
to break some stuff."
Doin It Rong
26
"Yeah, we're going to have to take
a couple of weeks out of the schedule
for refactoring, and that's probably going
to break some stuff."
Doin It Rong
27
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
http://refactoring.com/
"...a disciplined technique for
restructuring an existing body of code,
altering its internal structure
without changing its
external behavior."
29
Tests are implied.
-Katrina Owen,
“Therapeutic Refactoring”
30
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
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
Re·fac·tor·ing (noun)
A technique for
restructuring code
without changing behavior
33
Re·fac·tor (verb)
To restructure code
without changing behavior
34
Tell a clearer story
with fewer details
35
Re·fac·tor·ing (noun)
A language that describes
ways to make your code
suck less.
36
THESISES
37
THESISES
THESES
38
THESISES
THESES
THESII
39
THESISES
THESES
THESII
MY POINT(S)
40
You're probably already fluent
in refactoring.
Level 1:
RenameVariable; Rename Method.
41
You can become more fluent in
refactoring.
It just takes practice.
42
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
Refactoring Session
44
Used with:
• Permission
• Obfuscation
• Respect
Production Rails Code
45
Schedule Cable Installs
46
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
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
http://scientopia.org/blogs/whitecoatunderground/2009/06/10/my-head-just-asploded-twice/
Complexity
49
http://shipitsquirrel.github.io/
Ship it!
50
http://shipitsquirrel.github.io/
Ship Shit!
51
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
~800 lines
52
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
~800 lines
53
Make the Job Smaller
54
Replace Method with
Method Object
55
class InstallationsController <
ActionController::Base
def schedule
# LOTS OF CODE
end
end
56
class InstallationsController <
ActionController::Base
def schedule
end
end
class ScheduleInstallation
def call
end
end
# LOTS OF CODE
57
class InstallationsController <
ActionController::Base
def schedule
end
end
class ScheduleInstallation
def call
end
end
# LOTS OF CODE
58
class InstallationsController <
ActionController::Base
def schedule
end
end
class ScheduleInstallation
def call
end
end
ScheduleInstallation.new.call
# LOTS OF CODE
59
class ScheduleInstallation
def call
# LOTS OF CODE
end
end
60
class ScheduleInstallation
def initialize(controller)
@controller = controller
end
def call
# LOTS OF CODE
end
end
61
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)
end
end
62
Code Archaeology
63
if request.xhr?
# ...20 lines...
else
# ...22 lines...
end
64
if request.xml_http_request?
# ...20 lines...
else
# ...22 lines...
end
65
if request.xml_http_request?
begin
if @installation.pending_credit_check?
render :json => #...
return
end
#...
end
else
# ...22 lines...
end
66
if request.xhr?
begin
if @installation.pending_credit_check?
render :json => #...
return
end
#...
end
else
if @installation.pending_credit_check?
flash[:error] = #...
redirect_to installations_path(:city_id =>
end
begin
#...
end
67
ion.pending_credit_check?
n => #...
n.pending_credit_check?
= #...
nstallations_path(:city_id => @installation.city
68
check?
eck?
city_id => @installation.city_id, :view => "cale
69
lation.city_id, :view => "calendar") and return
70
if request.xhr?
begin
if @installation.pending_credit_check?
render :json => #...
return
end
#...
end
else
if @installation.pending_credit_check?
flash[:error] = #...
redirect_to installations_path(:city_id =>
return
end
begin
#...
end
if request.xhr?
if @installation.pend
render :json => #..
return
end
else
if @installation.pend
flash[:error] = #..
redirect_to(...) an
return
end
end
if request.xhr?
#...
else
#...71
if request.xhr?
#...
else
#...
end
if request.xhr?
#...
else
#...
end
ZOMG
duplication!!!1!!
72
if request.xhr?
if @installation.pending_credit_check?
#...
end
else
if @installation.pending_credit_check?
#...
end
end
if request.xhr?
#...
else
#...
end
73
Emphasis
74
if request.xhr?
if @installation.pending_credit_check?
#...
end
else
if @installation.pending_credit_check?
#...
end
end
75
Flatten Nested
Conditionals
source: Michael Feathers,
writing for Dr. Dobbs
76
if request.xhr?
if @installation.pending_credit_check?
render :json => #...
return
end
else
if @installation.pending_credit_check?
flash[:error] = #...
redirect_to #...
return
end
end
77
if ajax
if pending_credit_check
render :json => #...
return
end
else
if pending_credit_check
flash[:error] = #...
redirect_to #...
return
end
end
78
if ajax
if pending_credit_check
render :json => #...
return
end
else
if pending_credit_check
flash[:error] = #...
redirect_to #...
return
end
end
if ajax
if pending_credit_che
render :json => #..
return
end
end
if not ajax
if pending_credit_che
flash[:error] = #..
redirect_to #...
return
end
end
79
if ajax
if pending_credit_check
render :json => #...
return
end
end
if not ajax
if pending_credit_check
flash[:error] = #...
redirect_to #...
return
end
end
if ajax && pending_cred
render :json => #...
return
end
if (not ajax) && pendin
flash[:error] = #...
redirect_to #...
return
end
80
if ajax && pending_credit_check
render :json => #...
return
end
if (not ajax) && pending_credit_check
flash[:error] = #...
redirect_to #...
return
end
if pending_credit_check
if ajax
render :json => #..
return
end
if not ajax
flash[:error] = #..
redirect_to #...
return
end
end
81
if pending_credit_check
if ajax
render :json => #...
return
end
if not ajax
flash[:error] = #...
redirect_to #...
return
end
end
if pending_credit_check
if ajax
render :json => #..
return
else
flash[:error] = #..
redirect_to #...
return
end
end
82
if pending_credit_check
if ajax
render :json => #...
return
else
flash[:error] = #...
redirect_to #...
return
end
end
if pending_credit_check
if ajax
render :json => #..
else
flash[:error] = #..
redirect_to #...
end
return
end
83
if ajax
if pending_credit_check
render :json => #...
return
end
else
if pending_credit_check
flash[:error] = #...
redirect_to #...
return
end
end
if pending_credit_check
if ajax
render :json => #..
else
flash[:error] = #..
redirect_to #...
end
return
end
84
if pending_credit_check
if ajax
render :json => #...
else
flash[:error] = #...
redirect_to #...
end
return
end
if pending_credit_check
cant_schedule_while_c
return
end
85
Exception Handling
86
raise “wtf” if coin.toss.heads?begin
raise “wtf” if coin.t
end
87
begin
raise “wtf” if coin.toss.heads?
end
begin
raise “wtf” if coin.t
rescue => e
raise e
end
88
begin
raise “wtf” if coin.toss.heads?
rescue => e
raise e
end
89
begin
begin
raise “wtf” if coin.toss.heads?
rescue
#...
end
rescue => e
raise e
end
90
begin
begin
raise “wtf” if coin.toss.heads?
rescue
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
rescue => e
raise e
end
begin
begin
raise “wtf” if coin
rescue
if request.xhr?
raise “tfw” if tu
else
raise “yak” if Mo
end
end
rescue => e
if request.xhr?
raise e
else
raise e
end
end91
begin
begin
raise “wtf” if coin.toss.heads?
rescue
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
rescue => e
if request.xhr?
raise e
else
raise e
end
end
begin
begin
raise “wtf” if coin
rescue
if request.xhr?
# DO NOTHING
else
raise “yak” if Mo
end
end
rescue => e
if request.xhr?
raise “tfw” if tues
else
raise e
end
end92
begin
begin
raise “wtf” if coin.toss.heads?
rescue
if request.xhr?
# DO NOTHING
else
raise “yak” if Moon.gibbous?
end
end
rescue => e
if request.xhr?
raise “tfw” if tuesday?
else
raise e
end
end
begin
begin
raise “wtf” if coin
rescue
if request.xhr?
# DO NOTHING
else
# DO NOTHING
end
end
rescue => e
if request.xhr?
raise “tfw” if tues
else
raise “yak” if Moon
end
end93
begin
begin
raise “wtf” if coin.toss.heads?
rescue
if request.xhr?
# DO NOTHING
else
# DO NOTHING
end
end
rescue => e
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
begin
begin
raise “wtf” if coin
rescue
# DO NOTHING
end
rescue => e
if request.xhr?
raise “tfw” if tues
else
raise “yak” if Moon
end
end
94
begin
begin
raise “wtf” if coin.toss.heads?
rescue
# DO NOTHING
end
rescue => e
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
begin
begin
raise “wtf” if coin
end
rescue => e
if request.xhr?
raise “tfw” if tues
else
raise “yak” if Moon
end
end
95
begin
begin
raise “wtf” if coin.toss.heads?
end
rescue => e
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
begin
raise “wtf” if coin.t
rescue => e
if request.xhr?
raise “tfw” if tues
else
raise “yak” if Moon
end
end
96
begin
raise “wtf” if coin.toss.heads?
rescue => e
if request.xhr?
raise “tfw” if tuesday?
else
raise “yak” if Moon.gibbous?
end
end
begin
raise “wtf” if coin.t
rescue => e
handle_exception(e)
end
97
Training Montage
98
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
end
end
99
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
end
end
100
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
end
end
101
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
end
end
102
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
end
end
103
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
end
end
104
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
end
end
105
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
end
end
106
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
end
end
107
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
end
end
108
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
end
end
request.xhr?
109
Under The Rug
110
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
class ScheduleInstallation
private
def scheduling_failed
if request.xhr?
render :json => {:errors => [#...
else
flash[:error] = #...
redirect_to #...
end
end
end
112
Single Responsibility
Principle
113
ScheduleInstallation
ScheduleInstallationAnd
DoOneThingForAJAXRequestsAnd
DoSomethingElseForHTMLRequests
114
ScheduleInstallation
ScheduleInstallation And
DoOneThingForAJAXRequests And
DoSomethingElseForHTMLRequests
115
“Methods, like classes,
should have a single
responsibility.”
-Sandi Metz
116
http://en.wikipedia.org/wiki/File:Bill_%26_Ted%27s_Excellent_Adventure_(Original_Motion_Picture_Soundtrack).jpg
117
http://en.wikipedia.org/wiki/File:Paris_Tuileries_Garden_Facepalm_statue.jpg
118
Single Responsibility
Principle
Every class should have a single
responsibility, and that responsibility
should be entirely encapsulated
by the class.
119
ScheduleInstallation
ScheduleInstallation And
DoOneThingForAJAXRequests And
DoSomethingElseForHTMLRequests
120
Responder
121
122
InstallationsController
123
InstallationsController
ScheduleInstallation
???
124
InstallationsController
Responder
???
ScheduleInstallation
???
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_cleanup
end
class Responder
end
class ScheduleInstallat
def call
end
class Responder
def cannot_schedule_w
def handle_exception(
def scheduling_failed
def scheduling_succee
def do_post_success_c
end
125
126
Dualism
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
if request.xhr?
# do foo
else
# do bar
end
Replace Conditional
With Polymorphism
129
class Responder
def cannot_schedule_while_credit_check_pending
def handle_exception(e)
def scheduling_failed
def scheduling_succeeded
def do_post_success_cleanup
end
class AJAXResponder
def
cannot_schedule_while_cre
def handle_exception(e)
def scheduling_failed
def scheduling_succeede
def do_post_success_cle
end
class HTMLResponder
def
cannot_schedule_while_cre
def handle_exception(e)
def scheduling_failed
def scheduling_succeede
def do_post_success_cle
end
class AJAXResponder
def scheduling_failed
if request.xhr?
render :json => #...
else
flash[:error] = #...
redirect_to #...
end
end
end
class HTMLResponder
def scheduling_failed
if request.xhr?
render :json => #...
else
flash[:error] = #...
redirect_to #...
end
end
end
class AJAXResponder
def scheduling_failed
render :json => #...
end
end
class HTMLResponder
def scheduling_failed
flash[:error] = #...
redirect_to #...
end
end
132
InstallationsController
Responder
???
ScheduleInstallation
???
class InstallationsController
< ActionController::Base
def schedule
responder = if request.xhr?
AJAXResponder.new(self)
else
HTMLResponder.new(self)
end
ScheduleInstallation.new(responder).call
end
end
LESSONS LEARNED
134
Refactoring is Math
135
Fast Characterization
Tests Rock
136
Embrace Duplication
if request.xhr?
137
0
2
4
6
8
10
Embrace Evil Hacks
138
Perspective Matters
Superficial design flaws
can conceal
fundamental design flaws
139
http://gomakemeasandwich.wordpress.com/2011/10/26/a-yeaf-of-gmmas-where-do-we-go-from-here/
Where Do We Go
From Here?
140
141
142
143
http://www.poodr.info/
144
Practice!
• Play with automated refactorings in an IDE
• Do them manually in the editor (wax on,
wax off)
145
Practice!
• Commit early, commit often:
‘git reset --hard’ is your friend!
• Use throwaway branches
• Write fast characterization tests
146
Fluent Refactoring
github.com/geeksam
/fluent-refactoring
Sam Livingston-Gray
geeksam@gmail.com
Twitter, Github: @geeksam
147

Más contenido relacionado

La actualidad más candente

WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011John Ford
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 
Tugas praktikukm pemrograman c++
Tugas praktikukm  pemrograman c++Tugas praktikukm  pemrograman c++
Tugas praktikukm pemrograman c++Dendi Riadi
 
SALARY MANAGEMENT SYSTEM IN C++
SALARY MANAGEMENT SYSTEM IN C++SALARY MANAGEMENT SYSTEM IN C++
SALARY MANAGEMENT SYSTEM IN C++vikram mahendra
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your projectMichelangelo van Dam
 
BLOOD DONATION SYSTEM IN C++
BLOOD DONATION SYSTEM IN C++BLOOD DONATION SYSTEM IN C++
BLOOD DONATION SYSTEM IN C++vikram mahendra
 
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013Mosky Liu
 

La actualidad más candente (12)

Nop2
Nop2Nop2
Nop2
 
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Tugas praktikukm pemrograman c++
Tugas praktikukm  pemrograman c++Tugas praktikukm  pemrograman c++
Tugas praktikukm pemrograman c++
 
SALARY MANAGEMENT SYSTEM IN C++
SALARY MANAGEMENT SYSTEM IN C++SALARY MANAGEMENT SYSTEM IN C++
SALARY MANAGEMENT SYSTEM IN C++
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Ip project
Ip projectIp project
Ip project
 
BLOOD DONATION SYSTEM IN C++
BLOOD DONATION SYSTEM IN C++BLOOD DONATION SYSTEM IN C++
BLOOD DONATION SYSTEM IN C++
 
Expressions and Variables
Expressions and VariablesExpressions and Variables
Expressions and Variables
 
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
MoSQL: More than SQL, but Less than ORM @ PyCon APAC 2013
 
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
 

Similar a Fluent Refactoring (Lone Star Ruby Conf 2013)

Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)ruthmcdavitt
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Benjamin Bock
 
Test First Teaching
Test First TeachingTest First Teaching
Test First TeachingSarah Allen
 
Fluent Refactoring (Cascadia Ruby Conf 2013)
Fluent Refactoring (Cascadia Ruby Conf 2013)Fluent Refactoring (Cascadia Ruby Conf 2013)
Fluent Refactoring (Cascadia Ruby Conf 2013)Sam Livingston-Gray
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Frege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMFrege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMDierk König
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Toolschrismdp
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Test-driven Development (TDD)
Test-driven Development (TDD)Test-driven Development (TDD)
Test-driven Development (TDD)Bran van der Meer
 
Programming python quick intro for schools
Programming python quick intro for schoolsProgramming python quick intro for schools
Programming python quick intro for schoolsDan Bowen
 
Coffee scriptisforclosers nonotes
Coffee scriptisforclosers nonotesCoffee scriptisforclosers nonotes
Coffee scriptisforclosers nonotesBrandon Satrom
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endThibault Imbert
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertFITC
 

Similar a Fluent Refactoring (Lone Star Ruby Conf 2013) (20)

Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
SoTWLG Intro to Code Bootcamps 2016 (Roger Nesbitt)
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
 
Test First Teaching
Test First TeachingTest First Teaching
Test First Teaching
 
Fluent Refactoring (Cascadia Ruby Conf 2013)
Fluent Refactoring (Cascadia Ruby Conf 2013)Fluent Refactoring (Cascadia Ruby Conf 2013)
Fluent Refactoring (Cascadia Ruby Conf 2013)
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Frege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMFrege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVM
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Tools
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Test-driven Development (TDD)
Test-driven Development (TDD)Test-driven Development (TDD)
Test-driven Development (TDD)
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Programming python quick intro for schools
Programming python quick intro for schoolsProgramming python quick intro for schools
Programming python quick intro for schools
 
Coffee scriptisforclosers nonotes
Coffee scriptisforclosers nonotesCoffee scriptisforclosers nonotes
Coffee scriptisforclosers nonotes
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an end
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault Imbert
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 

Último

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 

Último (20)

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 

Fluent Refactoring (Lone Star Ruby Conf 2013)