def simplifying_code
{
author: "Jonathan Cabas"
follow: "@jcabasc"
}
end
Refactoring
4. GDD: Guilt Driven Development.
3. Learning of new techniques.
1. Improve our code.
2. Keep it simple.
Why?
Refactoring
Without test:
With test:
Conditions
Refactoring
1. Intention Revealing Method.
2. Special Case.
3. Replace method with method
object.
Intention Revealing Method
2.You have comments that explain what / how to do a method.
(or Extract Method)
1. You have a snippet of code that can be grouped together.
3. Turn the fragment/comment into a method whose name
explains the purpose of the method.
Code describes.
4. Change the original method to use the new one.
Intention Revealing Method
2. A method does more than one thing.
3. You have comments about a method that does not explain
why you would call it.
Why?
4. The code is mixed with different levels of abstractions.
High-level and low-level operations.
1. A method is too long.
Intention Revealing Method
• http://www.codinghorror.com/blog/2008/07/coding-without-comments.htm
Resources
• http://ntcoding.blogspot.com.ar/2011/05/clean-code-tricks-intention-
revealing.html
• http://c2.com/cgi/wiki?ExtractMethod
• http://java.dzone.com/articles/clean-code-dont-mix-different
• http://signalvnoise.com/posts/3531-intention-revealing-methods
Special Case Object
Get rid of ifs or trys
Instead of returning null or some odd value, return a special
case that has the same interface as what the caller expects.
Very often, we would like to execute some action only if an
object is present:
if current_user
#cool stuff
end
undefined method 'send_for_beer' for nil:NilClass (NoMethodError)
def current_user
if session[:user_id]
User.find(session[:user_id])
end
end
def welcome
"Hello, " +
current_user ? current_username : "guest" +
", how are you today?"
end
if current_user
render_logout_button
else
render_login_button
end
if current_user && current_user.is_admin?
render_admin_site
end
if current_user
@posts = current_user.visible_posts
else
@posts = Post.published
end
if current_user
current_user.last_seen = Time.now
end
cart = if current_user
current_user.cart
else
SessionCart.new(session)
end
cart.add_item(some_item, 1)
class GuestUser
def initialize(session)
@session = session
end
end
class GuestUser
def initialize(session)
@session = session
end
end
def current_user
if session[:user_id]
User.find(session[:user_id])
else
GuestUser.new(session)
end
end
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
end
def welcome
"Hello, " +
current_user ? current_username : "guest" +
", how are you today?"
end
def welcome
“Hello,#{current_user.name}, how are you?”
end
class User
# ...
def authenticated?
true
end
end
if current_user
render_logout_button
else
render_login_button
end
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
def authenticated?
false
end
end
if current_user.authenticated?
render_logout_button
else
render_login_button
end
if current_user && current_user.is_admin?
render_admin_site
end
if current_user.is_admin?
render_admin_site
end
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
def authenticated?
false
end
def is_admin?
false
end
end
if current_user
@posts = current_user.visible_posts
else
@posts = Post.published
end
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
def authenticated?
false
end
def is_admin?
false
end
def visible_posts
Post.published
end
end@posts = current_user.visible_posts
if current_user
current_user.last_seen = Time.now
end
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
def authenticated?
false
end
def is_admin?
false
end
def visible_posts
Post.published
end
def last_seen_online=(time)
#NOOP
end
end
current_user.last_seen = Time.now
cart = if current_user
current_user.cart
else
SessionCart.new(session)
end
cart.add_item(some_item, 1)
class GuestUser
def initialize(session)
@session = session
end
def name
"Guest"
end
def authenticated?
false
end
def is_admin?
false
end
def visible_posts
Post.published
end
def last_seen_online=(time)
#NOOP
end
def cart
SessionCart.new(session)
end
end
current_user.cart.add_item(some_item, 1)
2. The need of a “do nothing”/ default behaviour.
Why?
1. You want to abstract the handling of null away from the
client. ( Treat the presence of a null reference in a transparent
way).
Special Case Object
Special Case Object
• http://martinfowler.com/eaaCatalog/specialCase.html
Resources
• http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/
• http://www.cs.oberlin.edu/~jwalker/nullObjPattern/
• http://nickknowlson.com/blog/2013/04/16/why-maybe-is-better-than-null/
• http://sourcemaking.com/design_patterns/null_object
• RubyTapas #112
Replace method with
method object
class Order
def price(primary_base_price, secondary_base_price, tertiary_base_price)
# 1 chillion lines of code, lots of local variables
end
end
Replace method with
method object
1. Create a class with same initialization arguments as BIG
method.
2. Copy & Paste the method's body in the new class, with no
arguments.
3. Replace original method with a call to the new class.
4. Apply “Extract method” to the class.
Replace method with
method object
1. You have a long method with a lot of temporary variables.
2. Your long method uses local variables in such a way that
you can’t apply “extract method”.
3. You don’t want to pass those local variables around as you
extract methods.
Why?
• http://confreaks.com/videos/1071-cascadiaruby2012-therapeutic-
refactoring
• http://www.refactoring.com/catalog/replaceMethodWithMethodObject.htm
• http://sourcemaking.com/refactoring/replace-method-with-method-object
Replace method with
method object
Resources
Thank you note

Simplifying Code: Koombea TechTalks

  • 1.
    def simplifying_code { author: "JonathanCabas" follow: "@jcabasc" } end
  • 2.
    Refactoring 4. GDD: GuiltDriven Development. 3. Learning of new techniques. 1. Improve our code. 2. Keep it simple. Why?
  • 3.
  • 4.
    Refactoring 1. Intention RevealingMethod. 2. Special Case. 3. Replace method with method object.
  • 5.
    Intention Revealing Method 2.Youhave comments that explain what / how to do a method. (or Extract Method) 1. You have a snippet of code that can be grouped together. 3. Turn the fragment/comment into a method whose name explains the purpose of the method. Code describes. 4. Change the original method to use the new one.
  • 6.
    Intention Revealing Method 2.A method does more than one thing. 3. You have comments about a method that does not explain why you would call it. Why? 4. The code is mixed with different levels of abstractions. High-level and low-level operations. 1. A method is too long.
  • 7.
    Intention Revealing Method •http://www.codinghorror.com/blog/2008/07/coding-without-comments.htm Resources • http://ntcoding.blogspot.com.ar/2011/05/clean-code-tricks-intention- revealing.html • http://c2.com/cgi/wiki?ExtractMethod • http://java.dzone.com/articles/clean-code-dont-mix-different • http://signalvnoise.com/posts/3531-intention-revealing-methods
  • 8.
    Special Case Object Getrid of ifs or trys Instead of returning null or some odd value, return a special case that has the same interface as what the caller expects. Very often, we would like to execute some action only if an object is present: if current_user #cool stuff end undefined method 'send_for_beer' for nil:NilClass (NoMethodError)
  • 9.
    def current_user if session[:user_id] User.find(session[:user_id]) end end defwelcome "Hello, " + current_user ? current_username : "guest" + ", how are you today?" end if current_user render_logout_button else render_login_button end if current_user && current_user.is_admin? render_admin_site end if current_user @posts = current_user.visible_posts else @posts = Post.published end if current_user current_user.last_seen = Time.now end cart = if current_user current_user.cart else SessionCart.new(session) end cart.add_item(some_item, 1) class GuestUser def initialize(session) @session = session end end
  • 10.
    class GuestUser def initialize(session) @session= session end end def current_user if session[:user_id] User.find(session[:user_id]) else GuestUser.new(session) end end class GuestUser def initialize(session) @session = session end def name "Guest" end end def welcome "Hello, " + current_user ? current_username : "guest" + ", how are you today?" end def welcome “Hello,#{current_user.name}, how are you?” end class User # ... def authenticated? true end end if current_user render_logout_button else render_login_button end class GuestUser def initialize(session) @session = session end def name "Guest" end def authenticated? false end end if current_user.authenticated? render_logout_button else render_login_button end if current_user && current_user.is_admin? render_admin_site end if current_user.is_admin? render_admin_site end class GuestUser def initialize(session) @session = session end def name "Guest" end def authenticated? false end def is_admin? false end end if current_user @posts = current_user.visible_posts else @posts = Post.published end class GuestUser def initialize(session) @session = session end def name "Guest" end def authenticated? false end def is_admin? false end def visible_posts Post.published end end@posts = current_user.visible_posts if current_user current_user.last_seen = Time.now end class GuestUser def initialize(session) @session = session end def name "Guest" end def authenticated? false end def is_admin? false end def visible_posts Post.published end def last_seen_online=(time) #NOOP end end current_user.last_seen = Time.now cart = if current_user current_user.cart else SessionCart.new(session) end cart.add_item(some_item, 1) class GuestUser def initialize(session) @session = session end def name "Guest" end def authenticated? false end def is_admin? false end def visible_posts Post.published end def last_seen_online=(time) #NOOP end def cart SessionCart.new(session) end end current_user.cart.add_item(some_item, 1)
  • 11.
    2. The needof a “do nothing”/ default behaviour. Why? 1. You want to abstract the handling of null away from the client. ( Treat the presence of a null reference in a transparent way). Special Case Object
  • 12.
    Special Case Object •http://martinfowler.com/eaaCatalog/specialCase.html Resources • http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/ • http://www.cs.oberlin.edu/~jwalker/nullObjPattern/ • http://nickknowlson.com/blog/2013/04/16/why-maybe-is-better-than-null/ • http://sourcemaking.com/design_patterns/null_object • RubyTapas #112
  • 13.
    Replace method with methodobject class Order def price(primary_base_price, secondary_base_price, tertiary_base_price) # 1 chillion lines of code, lots of local variables end end
  • 14.
    Replace method with methodobject 1. Create a class with same initialization arguments as BIG method. 2. Copy & Paste the method's body in the new class, with no arguments. 3. Replace original method with a call to the new class. 4. Apply “Extract method” to the class.
  • 15.
    Replace method with methodobject 1. You have a long method with a lot of temporary variables. 2. Your long method uses local variables in such a way that you can’t apply “extract method”. 3. You don’t want to pass those local variables around as you extract methods. Why?
  • 16.
    • http://confreaks.com/videos/1071-cascadiaruby2012-therapeutic- refactoring • http://www.refactoring.com/catalog/replaceMethodWithMethodObject.htm •http://sourcemaking.com/refactoring/replace-method-with-method-object Replace method with method object Resources
  • 17.