4. Refactor
• To restructure software by applying a series of refactorings without
changing its observable behavior.
• 在不改變程式外在⾏行為的情況下改進程式內部的架構
13年5月15⽇日星期三
8. It’s hard to begin.
• Refactor code 就是改動程式碼,改動就有可能出錯,⽽而沒有⼈人
希望⼀一個正常運⾏行的 production site 因為改爛 code ⽽而 crash 掉
• 為了不出錯,要準備好相對應的測試,以確保程式碼不會出
錯。
• 由以上兩點來講那就是會花上許多時間
• ⽽而這個花上許多時間的結果並不是實作了⼀一個新功能
13年5月15⽇日星期三
9. Refactor 的兩⼤大難關
• I was refactoring code that no one had asked me to work on
我在重構⼀一段沒⼈人叫我去改的程式碼
• I found it too hard to put tests in place, so I did it without them.
Which, naturally, broke some things
我發現實在太難加上測試了,所以我就沒測它,然後就有東⻄西
爛掉了
Reference: How do you stop yourself from refactoring working but awful code?
13年5月15⽇日星期三
10. Change your situation
• 為了要加上這個新的 Feature,我們原本的程式碼架構需要配合
做出⼀一些調整...
• When you need to refactor code you are supposed to work on,
have tests in place, but they don't have to be automated.
我需要重構這段程式碼,因為很難寫⾃自動化測試碼,所以我找
⼈人來做QA
13年5月15⽇日星期三
17. Extract Service Objects
• The action is complex
• The action reaches across multiple models
• The action interacts with an external service
• The action is not a core concern of the underlying model
• There are multiple ways of performing the action
13年5月15⽇日星期三
18. Refactor: AuctionService
class Auction
def bid_by(user)
return false unless user.can_bid?(self)
user.consume_points
self.update_price_and_time
self.set_winner(user)
user.save_weekly_bid_count
user.check_if_lucky_bid
self.auction_logs.create
end
end
class AuctionService
def initialize(auction, user)
@user = user
@auction = auction
end
def bid!
return false unless user_can_bid?
consume_user_points
update_auction_price_and_time
set_auction_winner
set_user_weekly_bid_count
check_user_if_lucky_bid
generate_logs
end
end
13年5月15⽇日星期三
19. Compare
• auction.bid_by(user) 也可以寫為 user.bid(auction),讓⼈人困惑。
• 原本被拆分為兩個 model 上的測試,現在全部集中在
AuctionService 這個 model 上了
• 只要看 AuctionService 的測試內容就可以完整明⽩白此規格的要求
• 原本 model 帶著許多只有在特定時候才會⽤用到的 method,拆出
去後這兩個 model 都變“輕”許多
13年5月15⽇日星期三
20. How Tests help you Refactor
• 最基本的幫助:你可以不⽤用擔⼼心改錯程式碼
• ⼀一個好的測試規格可以幫助你找到 Bad Smell
• 不⽤用硬是想著要⾃自動化測試。
Any effective test is better than no test at all.
13年5月15⽇日星期三