Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Thames Valley Meetup: Refactoring
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Jack Franklin
November 05, 2014
Technology
190
1
Share
Thames Valley Meetup: Refactoring
Jack Franklin
November 05, 2014
More Decks by Jack Franklin
See All by Jack Franklin
Advanced React Meetup: Testing JavaScript
jackfranklin
1
250
Components on the Web: Frontend NE
jackfranklin
1
840
ReactiveConf: Lessons Migrating Complex Software
jackfranklin
0
510
Front Trends: Migrating complex software
jackfranklin
1
830
Migrating from Angular to React: Manc React
jackfranklin
1
210
Half Stack Fest: Webpack
jackfranklin
4
580
FullStackFest: Elm for JS Developers
jackfranklin
1
260
Codelicious: Intro to ES2015
jackfranklin
0
410
PolyConf: Elm for JS Developers
jackfranklin
0
290
Other Decks in Technology
See All in Technology
Sansanの認証基盤を支えるアーキテクチャとその振り返り
sansantech
PRO
1
150
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
140
契約書からの情報抽出を行うLLMのスループットを、バッチ処理を用いて最大40%改善した話
sansantech
PRO
3
340
OCI技術資料 : 証明書サービス概要
ocise
1
7.2k
Network Firewall Proxyで 自前プロキシを消し去ることができるのか
gusandayo
0
160
JEDAI認定プログラム JEDAI Order 2026 受賞者一覧 / JEDAI Order 2026 Winners
databricksjapan
0
480
OCI技術資料 : ロード・バランサ 概要 - FLB・NLB共通
ocise
4
27k
脳が溶けた話 / Melted Brain
keisuke69
1
1.2k
Babylon.js Japan Activities (2026/4)
limes2018
0
140
AIにより大幅に強化された AWS Transform Customを触ってみる
0air
0
280
不確実性と戦いながら見積もりを作成するプロセス/mitsumori-process
hirodragon112
1
170
AWSで2番目にリリースされたサービスについてお話しします(諸説あります)
yama3133
0
110
Featured
See All Featured
The Spectacular Lies of Maps
axbom
PRO
1
670
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
240
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.2k
Why Our Code Smells
bkeepers
PRO
340
58k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.3k
The SEO identity crisis: Don't let AI make you average
varn
0
430
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
140
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
340
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
260
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
220
Visualization
eitanlees
150
17k
Transcript
Refactoring Reafctoirng
@Jack_Franklin
None
changing the design not the behaviour
None
None
None
beware, opinions!
"Any fool can write code for a computer to understand.
Good programmers write code that humans can understand" ! Martin Fowler
None
// create the carousel ! carousel( 400, 500, $('img'), 1000,
2000, true );
function carousel( height, width, images, speed, delay, autoPlay ) {
// code }
// create the carousel ! carousel({ height: 400, width: 500,
… });
var h = 400; var w = 400; var play
= true; var calc = function()… ! for (var key in things)
Name things after their intention
"There are only two hard things in Comp Sci, cache
invalidation and naming things" ! Phil Karlton
var placePin = function(x, y) ! var getLatLon = function(x,
y) ! var user = { coordinates: [x, y] }
var placePin = function(coords) ! var getLatLon = function(coords) !
var user = { coordinates: { x: 1, y: 2 } }
implicit knowledge
if I were to hand the code over to you,
what do I have to explain?
var drawGraph = function(width, height) { width = 160 +
width; height = 172.5 + height; }
None
! var drawGraph = function(width, height) { var graphWidthPad =
160; width = graphWidthPad + width; … }
implicit knowledge is what trips future you up in 6
months time
function someFunc() { doSomething() and.then.something.else(); maybe.even.more(); var x = 2;
var y = 3; keep.on.going(x); and.going.and.going(y); return on.and.on(); }
strive for reusable, composable functions
this makes sure they do one thing and one thing
well
and also makes them much easier to test
easy to test code is usually pretty good
var goToBeginning = function(carousel) { if(carousel.isAtEnd()) { carousel.goToStart(); } }
var goToBeginning = function(carousel) { if(carousel.isAtEnd()) { carousel.goToStart(); } }
carousel goToBeginning
carousel.goToBeginning = function() { if(this.isAtEnd()) { this.goToStart(); } }
Component Component Component Component Component Component Component Component Component Component
components should know little about each other
one thing well
doing this in real life
120 seconds
you will never get this right
you never know less about the problem
premature abstraction is the root of all evil
prefer duplication at first
/users ?created_at[gt]=2014-04-01 &created_at[lte]=2014-05-01 ! if params[:created_at][:gt] users = users.where("created_at >…")
if params[:created_at][:lte] …
if params[:created_at][:gt] users = users.where("created_at >…") ! if params[:created_at][:lte] …
! if params[:created_at][:gte] … ! if params[:created_at][:lt] …
None
filters = params[:created_at] ! map = { lte: '<=', gt:
'>', … } ! filters.reduce(User.all) do |col, (key, val)| sym = map[key] col.where("created_at #{sym} ?", …) end
None
you can be too clever for your own good
filters = params[:created_at] users = User.all ! filters.reduce(users) do |coll,
(key, val)| case key when :lte then coll.where(…) when :gt then coll.where(…) … end
None
prefer clarity of intent over succinct code
if something goes wrong, back out
git commit all the time
you should rebase before pushing anyway
it's a slow, methodical, mechanical process
test driving features
Can a user subscribe? • NO if they are the
owner of the blog • NO if they are an admin of the blog • NO if they are already subscribed to the blog • NO if the blog is private • Else, totally.
given input X I expect output Y
pure function! input X > same output Y no side
effects
you should strive for pure functions
they are easy to test and less prone to causing
large errors
Can a user subscribe? • NO if they are the
owner of the blog • NO if they are an admin of the blog • NO if they are already subscribed to the blog • NO if the blog is private • Else, totally.
it "returns true if the user can" do res =
UserSubscribe.can_subscribe? (user_id, blog) expect(res).to be(true) end
class UserSubscribe def self.can_subscribe? (user_id, blog) true end end
None
it "returns true if the user can" … ! it
"returns false if the blog is private" …
None
class UserSubscribe def self.can_subscribe? (user_id, blog) !blog.private? end end
None
it "returns true if the user can" … ! it
"returns false if the blog is private" … ! it "returns false if the user owns the blog" …
None
class UserSubscribe def self.can_subscribe?(user_id, blog) if blog.private? false elsif user.owns?(blog)
false else true end end end
None
it "returns true if the user can" … ! it
"returns false if the blog is private" … ! it "returns false if the user owns the blog" … ! it "returns false if the user is admin" …
class UserSubscribe def self.can_subscribe?(user_id, blog) if blog.private? false elsif user.owns?(blog)
false elsif user.is_admin?(blog) false else true end end end
it "returns true if the user can" … ! it
"returns false if the blog is private" … ! it "returns false if the user owns the blog" … ! it "returns false if the user is admin" … ! it "returns false if the user is subscribed" …
class UserSubscribe def self.can_subscribe?(user_id, blog) if blog.private? false elsif user.owns?(blog)
false elsif user.is_admin?(blog) false elsif user.is_subscribed?(blog) false else true end end end
None
the first implementation doesn't matter
the first implementation is about understanding the problem
None
class UserSubscribe def self.can_subscribe?(user_id, blog) if blog.private? || user.owns?(blog) ||
user.is_admin?(blog) || user.is_subscribed?(blog) false else true end end end
class UserSubscribe def self.can_subscribe?(user_id, blog) ! !(blog.private? || user.owns?(blog) ||
user.is_admin?(blog) || user.is_subscribed?(blog)) ! end end
class UserSubscribe def self.can_subscribe?(user_id, blog) ! return false if blog.private?
return false if user.owns?(blog) return false if … return false if … true end end
None
prefer clarity of intent over succinct code
TDD doesn't work every time
(but that doesn't mean you shouldn't write tests!)
but sometimes it might make sense to write the tests
afterwards...
#TODOs don't get done
None
49,732,824
Code Review
Code Review
None
Making a difficult change
refactor to make the change easy
make the change
RubyRogues #178 ! http://devchat.tv/ruby- rogues/episode-guide
Refactoring Book ! http://refactoring.com/
Thoughtbot Blog ! http:// robots.thoughtbot.com/
Thank You! ! @Jack_Franklin ! http://javascriptplayground.com/ the-refactoring-tales/