10/17/2006

Dry or Not DRY


DRY 也就是 Don't Repeat Yourself 的簡稱,Ruby on Rails 導入許多機制只是為了更好 DRY your code ,使用 DRY 可以有效減少需要維護的 Code。

不過也發生一些小問題,有些時候,到底要不要 DRY ? 像是 Partial Template 這個機制,本來也是為了 DRY 而產生的。可是遇到一個情況
當許多 template 都會呼叫到同一個 partial
但是每個 template 呼叫的 partial 都希望有微小的改變
像是 A template 是外面的人看到的頁面,他呼叫partial X ,你不希望 partial X出現管理的 link ,讓外人可以進入管理的頁面。但是B template 是已經經過認證的 User,他也呼叫 partial X,但是他卻希望partial X出現管理的 link 。
難道你要為了新增一個 link ,另外寫一個頁面?
這樣就不夠 DRY 了,所以我們其實可以在 Partail X 這樣搞
if params[:controller] == 'A_controller' and params[:action] == 'B_action'
show_link
end
其實parmas 變數裡面有 controller 跟 action 變數,可以記載這個 template 現在正在那邊。一般來說沒有用到的必要,因為 controller 跟 view 的對應是 1:1 的關係。只不過,我們用到 partial template 時,如果遇到剛剛的情況,可以使用這兩個變數來探知現在這個 partial 被那個 controller 跟 action 所呼叫,並且做出不同反應。

聽起來很棒,其實是另外一個問題的開始。Ruby on Rails 之所以 Controller 跟 Action 會預設 1:1 對應其實也讓 coder 清楚程式架構的因素在。如果你 過量 使用上述的方式,會讓你的 view code 出現
if params[:controller] == 'A_controller' and params[:action] == 'B_action'
show_link
elsif params[:controller] == 'C_controller' and params[:action] == 'D_action'
show_link2
elsif params[:controller] == 'E_controller' and params[:action] == 'F_action'
show_link3
elsif params[:controller] == 'G_controller' and params[:action] == 'H_action'
show_link4
elsif params[:controller] == 'I_controller' and params[:action] == 'J_action'
show_link5
elsif params[:controller] == 'K_controller' and params[:action] == 'L_action'
show_link6
elsif params[:controller] == 'M_controller' and params[:action] == 'N_action'
show_link7
end
這樣的code 太可怕了。
回到 Ruby on Rails 的根本,這一切的一切都是為了加快開發速度而設計的。
為什麼要使用 DRY ?因為要減少 Code 量,Code 量少就會減少 Code 的維護成本。減少 Code 維護成本才能增加開發速度。但是雖然我們使用 DRY 原則減少了程式的 code 量,但是卻增加了閱讀的難度。這有意義嗎?並且 view 層本來就不能安插太多程式,這會造成架構上的混亂。因為上述的情況並不會有效的減少 Code 維護成本,某種程度還會增高維護成本,所以為了大原則 加快開發速度 ,我們必須給予重寫。

但是話說回來
if params[:controller] == 'A_controller' and params[:action] == 'B_action'
show_link
end
這段對我來說並不會下降可讀性,卻又擁有 DRY 的優點,對我來說這是會加快開發速度的,所以我允許我自己這樣寫。一般來說,partial 出現 if 二選一,或是三選一我是允許的,四選一的話,重構吧。

凡事過與不及都不好,要怎麼取得平衡才是大學問呀。

沒有留言: