SlideShare a Scribd company logo
1 of 34
Download to read offline
REFACTORING WORKSHOP 
Bruce Li @ Rails Pacific 2014 
Please clone this repo 
https://github.com/ascendbruce/refactoring-workshop 
run bundle install 
and Check your ruby version
ABOUT ME 
• Li, Po-Chun a.k.a. Bruce Li 
• Work at Techbang 
• http://ascendbruce.logdown.com/ 
• @BruceToyRoom, @techbangtech
REFACTORING 
is important 
• Reduce maintenance cost 
• Technical debt is not about technology. It’s about 
people 
• programmer happiness is very important
TEST COVERAGE 
is important 
• Confident in changes 
• Code School, TeaLeaf are good start 
• SimpleCov and CodeClimate can make you 
happier while repairing test cases
PRY 
is useful 
• gem "pry-rails" 
gem "pry-byebug" # or pry-debugger for ruby 1.9 
• binding.pry # to entering debug mode 
• Commands: next, step, break, continue, exit 
• It’s all you need at first
COMMENTS IN CODE 
is bad (in some cases) 
• Ideally, code should describe itself. 
• Out-dated comments are worser than none. It’s 
actively misleading. 
• Comments is helpful for providing additional 
information or link to issue tracking history.
1. INTENTION REVEALING 
METHOD 
• Add comments if code need it. 
• Transform comments into methods. 
• Comments are now code. Code describes itself.
user_is_admitted?
user_is_admitted?
user_is_admitted? 
set_marketing_flash
user_is_admitted? 
set_marketing_flash
2. MOVE MODEL LOGIC INTO 
THE MODEL 
• Move the logic, which belongs to model, into the 
model 
• instance variable should change to self in model
class ProjectsController 
def new 
# @#$^$%&#%&*#$%& 
@project = Project.new 
! 
! 
@project.do_ooxx 
@project.xxoo = "xxoo" 
# &*%^&@#$! 
end 
end 
class Project 
! 
! 
! 
! 
end 
def do_something 
! 
! 
end
class ProjectsController 
def new 
# @#$^$%&#%&*#$%& 
@project = Project.new 
@project.do_something 
! 
! 
# &*%^&@#$! 
end 
end 
class Project 
! 
! 
! 
! 
end 
def do_something 
! 
! 
end 
@project.do_ooxx 
@project.xxoo = "xxoo"
class ProjectsController 
def new 
# @#$^$%&#%&*#$%& 
@project = Project.new 
@project.do_something 
! 
! 
# &*%^&@#$! 
end 
end 
class Project 
! 
! 
! 
! 
end 
def do_something 
! 
! 
end 
@project.do_ooxx 
@project.xxoo = "xxoo"
class ProjectsController 
def new 
# @#$^$%&#%&*#$%& 
@project = Project.new 
@project.do_something 
do_ooxx 
self.xxoo = "xxoo" 
! 
! 
# &*%^&@#$! 
end 
end 
class Project 
! 
! 
! 
! 
end 
def do_something 
! 
! 
end
3. REPLACE METHOD WITH 
METHOD OBJECT 
• Create a class with same initialization arguments as 
BIG method 
• Copy & Paste the method's body in the new class, 
with no arguments 
• Replace original method with a call to the new class 
• Apply "Intention Revealing Method" to the class
class OriginMethods 
def a_fat_method 
! 
! 
! 
! 
end 
end 
# $%@ + ($@# / ^%) 
# && ^ %& * #%%^ 
# wtf 
# and 100 lines...
class NewMethods 
def perform 
end 
end 
class OriginMethods 
def a_fat_method 
! 
! 
! 
! 
end 
end 
# $%@ + ($@# / ^%) 
# && ^ %& * #%%^ 
# wtf 
# and 100 lines...
class NewMethods 
def perform 
! 
! 
! 
! 
end 
end 
# $%@ + ($@# / ^%) 
# && ^ %& * #%%^ 
# wtf 
# and 100 lines... 
class OriginMethods 
def a_fat_method 
! 
! 
! 
! 
end 
end
class NewMethods 
def perform 
! 
! 
! 
! 
end 
end 
# $%@ + ($@# / ^%) 
# && ^ %& * #%%^ 
# wtf 
# and 100 lines... 
class OriginMethods 
def a_fat_method 
! 
! 
! 
! 
end 
end 
NewMethods.new.perform
class NewMethods 
! 
! 
! 
! 
def perform 
File.open(??????????) 
# ... 
end 
end 
! 
class OriginMethods 
def a_fat_method(file_name) 
NewMethods.new.perform 
end 
end 
?
class NewMethods 
! 
! 
! 
! 
def perform 
File.open( ) 
# ... 
end 
end 
! 
class OriginMethods 
def a_fat_method(file_name) 
NewMethods.new 
end 
end
class NewMethods 
! 
! 
! 
! 
def perform 
File.open( ) 
# ... 
end 
end 
! 
class OriginMethods 
def a_fat_method(file_name) 
NewMethods.new 
end 
end 
(file_name).perform
class NewMethods 
! 
! 
! 
! 
def perform 
def initialize(file_name) 
@file_name = file_name 
end 
File.open( ) 
# ... 
end 
end 
! 
class OriginMethods 
def a_fat_method(file_name) 
NewMethods.new 
end 
end 
(file_name).perform
class NewMethods 
! 
! 
! 
! 
def perform 
def initialize(file_name) 
@file_name = file_name 
end 
@file_name 
File.open( ) 
# ... 
end 
end 
! 
class OriginMethods 
def a_fat_method(file_name) 
NewMethods.new 
end 
end 
(file_name).perform
4. SERVICE OBJECT 
• If we add new functionality to an object and: 
• It couples to a new dependency 
• It loses cohesion 
• Testing gets harder and slower
4. SERVICE OBJECT 
• If it's a domain concept, it's an Object. If it's only 
an algorithm (no state) we call it a Service. 
• Delegate to the Service Object
5. FORM OBJECT 
• accepts_nested_attributes_for is hard to track 
• Making very different forms for the same object is 
a pain. The model is messed up
5. FORM OBJECT 
• include ActiveModel::Model 
• Set attr_reader for related models 
• Set attr_accessor for accepted fields 
• Add validators (ActiveModel::Model will take care of validation and 
errors) 
• Define persisted? method (false for create, true for update form) 
• Add initialize, save, update etc… if needed
REFERENCE 
• Crisp's Blog - Good and Bad Technical Debt 
• RailsCasts - Form Objects 
• 7 Patterns to Refactor Fat ActiveRecord Models

More Related Content

What's hot

Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application TestingYnon Perek
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
 
Sizzle jQCon San Francisco 2012
Sizzle jQCon San Francisco 2012Sizzle jQCon San Francisco 2012
Sizzle jQCon San Francisco 2012livelogos
 
Drupal8 Front-end Automated Testing
Drupal8 Front-end Automated TestingDrupal8 Front-end Automated Testing
Drupal8 Front-end Automated TestingRuben Teijeiro
 
Webcomponents are your frameworks best friend
Webcomponents are your frameworks best friendWebcomponents are your frameworks best friend
Webcomponents are your frameworks best friendFilip Bruun Bech-Larsen
 
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAutomating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAdler Hsieh
 
Thing to love in Clojure
Thing to love in ClojureThing to love in Clojure
Thing to love in ClojureJiří Knesl
 
Reacting to the Isomorphic Buzz
Reacting to the Isomorphic BuzzReacting to the Isomorphic Buzz
Reacting to the Isomorphic BuzzBruce Coddington
 
How I ignored, discovered then loved design patterns - Abdelkader Bouadjadja
How I ignored, discovered then loved design patterns - Abdelkader BouadjadjaHow I ignored, discovered then loved design patterns - Abdelkader Bouadjadja
How I ignored, discovered then loved design patterns - Abdelkader BouadjadjaAbdelkader Bouadjadja
 
Never fear, the customizer is here!
Never fear, the customizer is here!Never fear, the customizer is here!
Never fear, the customizer is here!Cameron Jones
 
Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011dimakovalenko
 
Angular.JS: Do it right
Angular.JS: Do it rightAngular.JS: Do it right
Angular.JS: Do it rightEugene Zharkov
 
API Prefetching - HTML5DevConf - Oct. 21, 2014
API Prefetching - HTML5DevConf - Oct. 21, 2014API Prefetching - HTML5DevConf - Oct. 21, 2014
API Prefetching - HTML5DevConf - Oct. 21, 2014JonAbrams
 
Building testable chrome extensions
Building testable chrome extensionsBuilding testable chrome extensions
Building testable chrome extensionsSeth McLaughlin
 
Marrying angular rails
Marrying angular railsMarrying angular rails
Marrying angular railsVolker Tietz
 
Cucumber.js: Cuke up your JavaScript!
Cucumber.js: Cuke up your JavaScript!Cucumber.js: Cuke up your JavaScript!
Cucumber.js: Cuke up your JavaScript!Julien Biezemans
 

What's hot (20)

Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application Testing
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
I Promise You
I Promise YouI Promise You
I Promise You
 
Sizzle jQCon San Francisco 2012
Sizzle jQCon San Francisco 2012Sizzle jQCon San Francisco 2012
Sizzle jQCon San Francisco 2012
 
Drupal8 Front-end Automated Testing
Drupal8 Front-end Automated TestingDrupal8 Front-end Automated Testing
Drupal8 Front-end Automated Testing
 
Webcomponents are your frameworks best friend
Webcomponents are your frameworks best friendWebcomponents are your frameworks best friend
Webcomponents are your frameworks best friend
 
Frameworks and webcomponents
Frameworks and webcomponentsFrameworks and webcomponents
Frameworks and webcomponents
 
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAutomating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
 
Cucumber
CucumberCucumber
Cucumber
 
Style Is Cool
Style Is CoolStyle Is Cool
Style Is Cool
 
Thing to love in Clojure
Thing to love in ClojureThing to love in Clojure
Thing to love in Clojure
 
Reacting to the Isomorphic Buzz
Reacting to the Isomorphic BuzzReacting to the Isomorphic Buzz
Reacting to the Isomorphic Buzz
 
How I ignored, discovered then loved design patterns - Abdelkader Bouadjadja
How I ignored, discovered then loved design patterns - Abdelkader BouadjadjaHow I ignored, discovered then loved design patterns - Abdelkader Bouadjadja
How I ignored, discovered then loved design patterns - Abdelkader Bouadjadja
 
Never fear, the customizer is here!
Never fear, the customizer is here!Never fear, the customizer is here!
Never fear, the customizer is here!
 
Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011
 
Angular.JS: Do it right
Angular.JS: Do it rightAngular.JS: Do it right
Angular.JS: Do it right
 
API Prefetching - HTML5DevConf - Oct. 21, 2014
API Prefetching - HTML5DevConf - Oct. 21, 2014API Prefetching - HTML5DevConf - Oct. 21, 2014
API Prefetching - HTML5DevConf - Oct. 21, 2014
 
Building testable chrome extensions
Building testable chrome extensionsBuilding testable chrome extensions
Building testable chrome extensions
 
Marrying angular rails
Marrying angular railsMarrying angular rails
Marrying angular rails
 
Cucumber.js: Cuke up your JavaScript!
Cucumber.js: Cuke up your JavaScript!Cucumber.js: Cuke up your JavaScript!
Cucumber.js: Cuke up your JavaScript!
 

Similar to Refactoring Workshop (Rails Pacific 2014)

Modernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesModernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesiMasters
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in StyleBhavin Javia
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)lazyatom
 
Metaprogramming + Ds Ls
Metaprogramming + Ds LsMetaprogramming + Ds Ls
Metaprogramming + Ds LsArrrrCamp
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# DevelopersCory Foy
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
Continuous Integration For Rails Project
Continuous Integration For Rails ProjectContinuous Integration For Rails Project
Continuous Integration For Rails ProjectLouie Zhao
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018Mike Harris
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Test First Teaching
Test First TeachingTest First Teaching
Test First TeachingSarah Allen
 
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
 
Techtalk design patterns
Techtalk design patternsTechtalk design patterns
Techtalk design patternsJan Berdajs
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsTristan Gomez
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindiaComplaints
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 

Similar to Refactoring Workshop (Rails Pacific 2014) (20)

Modernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesModernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul Jones
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)
 
Metaprogramming + Ds Ls
Metaprogramming + Ds LsMetaprogramming + Ds Ls
Metaprogramming + Ds Ls
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 
Refactoring
RefactoringRefactoring
Refactoring
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
Continuous Integration For Rails Project
Continuous Integration For Rails ProjectContinuous Integration For Rails Project
Continuous Integration For Rails Project
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Rails OO views
Rails OO viewsRails OO views
Rails OO views
 
Test First Teaching
Test First TeachingTest First Teaching
Test First Teaching
 
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
 
Php
PhpPhp
Php
 
Techtalk design patterns
Techtalk design patternsTechtalk design patterns
Techtalk design patterns
 
Dsl
DslDsl
Dsl
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and Patterns
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
 
Ruby basics
Ruby basicsRuby basics
Ruby basics
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 

More from Bruce Li

RSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letRSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letBruce Li
 
Unlock dependency between client teams and API team with API mock and proxy
Unlock dependency between client teams and API team with API mock and proxyUnlock dependency between client teams and API team with API mock and proxy
Unlock dependency between client teams and API team with API mock and proxyBruce Li
 
011 優化時間分配的 app 跟心得
011 優化時間分配的 app 跟心得011 優化時間分配的 app 跟心得
011 優化時間分配的 app 跟心得Bruce Li
 
Rails Code Club 3 @ Taipei
Rails Code Club 3 @ TaipeiRails Code Club 3 @ Taipei
Rails Code Club 3 @ TaipeiBruce Li
 
Rails Code Club 2 @ Taipei
Rails Code Club 2 @ TaipeiRails Code Club 2 @ Taipei
Rails Code Club 2 @ TaipeiBruce Li
 
010 Better and Better 工程師就業兩年多的心得雜談
010 Better and Better 工程師就業兩年多的心得雜談010 Better and Better 工程師就業兩年多的心得雜談
010 Better and Better 工程師就業兩年多的心得雜談Bruce Li
 
009 增進效率的雜七雜八mac快速鍵與設定 part 2
009 增進效率的雜七雜八mac快速鍵與設定 part 2009 增進效率的雜七雜八mac快速鍵與設定 part 2
009 增進效率的雜七雜八mac快速鍵與設定 part 2Bruce Li
 
008 vim超基礎入門
008 vim超基礎入門008 vim超基礎入門
008 vim超基礎入門Bruce Li
 
007 Facebook Open Graph 相關開發簡單介紹 公開版
007 Facebook Open Graph 相關開發簡單介紹 公開版007 Facebook Open Graph 相關開發簡單介紹 公開版
007 Facebook Open Graph 相關開發簡單介紹 公開版Bruce Li
 
006 實作小玩具功能:chrome desktop notification
006 實作小玩具功能:chrome desktop notification006 實作小玩具功能:chrome desktop notification
006 實作小玩具功能:chrome desktop notificationBruce Li
 
004 動機 單純的力量 讀書心得
004 動機 單純的力量 讀書心得004 動機 單純的力量 讀書心得
004 動機 單純的力量 讀書心得Bruce Li
 
003 Ruby小觀念與小技巧Part2
003 Ruby小觀念與小技巧Part2003 Ruby小觀念與小技巧Part2
003 Ruby小觀念與小技巧Part2Bruce Li
 
002 增進效率的有的沒的快速鍵與設定
002 增進效率的有的沒的快速鍵與設定002 增進效率的有的沒的快速鍵與設定
002 增進效率的有的沒的快速鍵與設定Bruce Li
 
001 Ruby小觀念與小技巧
001 Ruby小觀念與小技巧001 Ruby小觀念與小技巧
001 Ruby小觀念與小技巧Bruce Li
 

More from Bruce Li (14)

RSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letRSpec best practice - avoid using before and let
RSpec best practice - avoid using before and let
 
Unlock dependency between client teams and API team with API mock and proxy
Unlock dependency between client teams and API team with API mock and proxyUnlock dependency between client teams and API team with API mock and proxy
Unlock dependency between client teams and API team with API mock and proxy
 
011 優化時間分配的 app 跟心得
011 優化時間分配的 app 跟心得011 優化時間分配的 app 跟心得
011 優化時間分配的 app 跟心得
 
Rails Code Club 3 @ Taipei
Rails Code Club 3 @ TaipeiRails Code Club 3 @ Taipei
Rails Code Club 3 @ Taipei
 
Rails Code Club 2 @ Taipei
Rails Code Club 2 @ TaipeiRails Code Club 2 @ Taipei
Rails Code Club 2 @ Taipei
 
010 Better and Better 工程師就業兩年多的心得雜談
010 Better and Better 工程師就業兩年多的心得雜談010 Better and Better 工程師就業兩年多的心得雜談
010 Better and Better 工程師就業兩年多的心得雜談
 
009 增進效率的雜七雜八mac快速鍵與設定 part 2
009 增進效率的雜七雜八mac快速鍵與設定 part 2009 增進效率的雜七雜八mac快速鍵與設定 part 2
009 增進效率的雜七雜八mac快速鍵與設定 part 2
 
008 vim超基礎入門
008 vim超基礎入門008 vim超基礎入門
008 vim超基礎入門
 
007 Facebook Open Graph 相關開發簡單介紹 公開版
007 Facebook Open Graph 相關開發簡單介紹 公開版007 Facebook Open Graph 相關開發簡單介紹 公開版
007 Facebook Open Graph 相關開發簡單介紹 公開版
 
006 實作小玩具功能:chrome desktop notification
006 實作小玩具功能:chrome desktop notification006 實作小玩具功能:chrome desktop notification
006 實作小玩具功能:chrome desktop notification
 
004 動機 單純的力量 讀書心得
004 動機 單純的力量 讀書心得004 動機 單純的力量 讀書心得
004 動機 單純的力量 讀書心得
 
003 Ruby小觀念與小技巧Part2
003 Ruby小觀念與小技巧Part2003 Ruby小觀念與小技巧Part2
003 Ruby小觀念與小技巧Part2
 
002 增進效率的有的沒的快速鍵與設定
002 增進效率的有的沒的快速鍵與設定002 增進效率的有的沒的快速鍵與設定
002 增進效率的有的沒的快速鍵與設定
 
001 Ruby小觀念與小技巧
001 Ruby小觀念與小技巧001 Ruby小觀念與小技巧
001 Ruby小觀念與小技巧
 

Recently uploaded

Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 

Recently uploaded (20)

Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 

Refactoring Workshop (Rails Pacific 2014)

  • 1. REFACTORING WORKSHOP Bruce Li @ Rails Pacific 2014 Please clone this repo https://github.com/ascendbruce/refactoring-workshop run bundle install and Check your ruby version
  • 2. ABOUT ME • Li, Po-Chun a.k.a. Bruce Li • Work at Techbang • http://ascendbruce.logdown.com/ • @BruceToyRoom, @techbangtech
  • 3. REFACTORING is important • Reduce maintenance cost • Technical debt is not about technology. It’s about people • programmer happiness is very important
  • 4. TEST COVERAGE is important • Confident in changes • Code School, TeaLeaf are good start • SimpleCov and CodeClimate can make you happier while repairing test cases
  • 5. PRY is useful • gem "pry-rails" gem "pry-byebug" # or pry-debugger for ruby 1.9 • binding.pry # to entering debug mode • Commands: next, step, break, continue, exit • It’s all you need at first
  • 6. COMMENTS IN CODE is bad (in some cases) • Ideally, code should describe itself. • Out-dated comments are worser than none. It’s actively misleading. • Comments is helpful for providing additional information or link to issue tracking history.
  • 7. 1. INTENTION REVEALING METHOD • Add comments if code need it. • Transform comments into methods. • Comments are now code. Code describes itself.
  • 8.
  • 9.
  • 10.
  • 15. 2. MOVE MODEL LOGIC INTO THE MODEL • Move the logic, which belongs to model, into the model • instance variable should change to self in model
  • 16. class ProjectsController def new # @#$^$%&#%&*#$%& @project = Project.new ! ! @project.do_ooxx @project.xxoo = "xxoo" # &*%^&@#$! end end class Project ! ! ! ! end def do_something ! ! end
  • 17. class ProjectsController def new # @#$^$%&#%&*#$%& @project = Project.new @project.do_something ! ! # &*%^&@#$! end end class Project ! ! ! ! end def do_something ! ! end @project.do_ooxx @project.xxoo = "xxoo"
  • 18. class ProjectsController def new # @#$^$%&#%&*#$%& @project = Project.new @project.do_something ! ! # &*%^&@#$! end end class Project ! ! ! ! end def do_something ! ! end @project.do_ooxx @project.xxoo = "xxoo"
  • 19. class ProjectsController def new # @#$^$%&#%&*#$%& @project = Project.new @project.do_something do_ooxx self.xxoo = "xxoo" ! ! # &*%^&@#$! end end class Project ! ! ! ! end def do_something ! ! end
  • 20. 3. REPLACE METHOD WITH METHOD OBJECT • Create a class with same initialization arguments as BIG method • Copy & Paste the method's body in the new class, with no arguments • Replace original method with a call to the new class • Apply "Intention Revealing Method" to the class
  • 21. class OriginMethods def a_fat_method ! ! ! ! end end # $%@ + ($@# / ^%) # && ^ %& * #%%^ # wtf # and 100 lines...
  • 22. class NewMethods def perform end end class OriginMethods def a_fat_method ! ! ! ! end end # $%@ + ($@# / ^%) # && ^ %& * #%%^ # wtf # and 100 lines...
  • 23. class NewMethods def perform ! ! ! ! end end # $%@ + ($@# / ^%) # && ^ %& * #%%^ # wtf # and 100 lines... class OriginMethods def a_fat_method ! ! ! ! end end
  • 24. class NewMethods def perform ! ! ! ! end end # $%@ + ($@# / ^%) # && ^ %& * #%%^ # wtf # and 100 lines... class OriginMethods def a_fat_method ! ! ! ! end end NewMethods.new.perform
  • 25. class NewMethods ! ! ! ! def perform File.open(??????????) # ... end end ! class OriginMethods def a_fat_method(file_name) NewMethods.new.perform end end ?
  • 26. class NewMethods ! ! ! ! def perform File.open( ) # ... end end ! class OriginMethods def a_fat_method(file_name) NewMethods.new end end
  • 27. class NewMethods ! ! ! ! def perform File.open( ) # ... end end ! class OriginMethods def a_fat_method(file_name) NewMethods.new end end (file_name).perform
  • 28. class NewMethods ! ! ! ! def perform def initialize(file_name) @file_name = file_name end File.open( ) # ... end end ! class OriginMethods def a_fat_method(file_name) NewMethods.new end end (file_name).perform
  • 29. class NewMethods ! ! ! ! def perform def initialize(file_name) @file_name = file_name end @file_name File.open( ) # ... end end ! class OriginMethods def a_fat_method(file_name) NewMethods.new end end (file_name).perform
  • 30. 4. SERVICE OBJECT • If we add new functionality to an object and: • It couples to a new dependency • It loses cohesion • Testing gets harder and slower
  • 31. 4. SERVICE OBJECT • If it's a domain concept, it's an Object. If it's only an algorithm (no state) we call it a Service. • Delegate to the Service Object
  • 32. 5. FORM OBJECT • accepts_nested_attributes_for is hard to track • Making very different forms for the same object is a pain. The model is messed up
  • 33. 5. FORM OBJECT • include ActiveModel::Model • Set attr_reader for related models • Set attr_accessor for accepted fields • Add validators (ActiveModel::Model will take care of validation and errors) • Define persisted? method (false for create, true for update form) • Add initialize, save, update etc… if needed
  • 34. REFERENCE • Crisp's Blog - Good and Bad Technical Debt • RailsCasts - Form Objects • 7 Patterns to Refactor Fat ActiveRecord Models