從這一集開始,我們一起探討一下關於重構的話題。重構是指在不改變軟件功能的前提下對代碼進行優化,以達到去除冗餘代碼、提高代碼可讀性及可維護性的的目的。
下面頁面是一個用戶列表,點擊用戶名後顯示用戶資料。需要注意的是,有些用戶有中間名(middle name)有些則沒有。
瀏覽器中顯示的列表頁及用戶資料頁.
先看看列表頁的代碼:
<h1>Users</h1>
<ul>
<% for user in @users %>
<li>
<a href="<%= user_path(user) %>">
<%= user.first_name %>
<%= "#{user.middle_initial}." unless user.middle_initial.nil? %>
<%= user.last_name %>
</a>
</li>
<% end %>
</ul>
列表頁代碼
上面的代碼先是獲取所有的用戶對象,進行循環。<a>標籤中的三行代碼用來顯示用戶名。接下來,是用戶資料頁面:
<h1>Profile</h1>
<p>
Name:
<%= @user.first_name %>
<%= "#{@user.middle_initial}." unless @user.middle_initial.nil? %>
<%= @user.last_name %>
</p>
<%= link_to 'Users List', users_path %>
用戶資料頁代碼
用戶資料頁面和列表頁一樣,也用三行代碼顯示用戶名。很明顯做了重複的工作,這裏便成爲我們的優化點。分析一下代碼,其中第一行和第三行分別顯示名稱和姓氏;第二行是當有中間名時顯示外加一個點,沒有中間名的時候什麼都不顯示。
如何開始這次重構?
可以把這個通用邏輯抽取到一個工具方法中,但我覺得這三行邏輯與User
模型的關聯更緊密些。所以應該將它們抽取到模型中更加合理。在User
類中增加一個名爲full_name
的方法.將頁面中的代碼移動到這個方法中,給一個局部變量賦值並返回。
class User < ActiveRecord::Base
def full_name
name = first_name + ' '
name += "#{middle_initial}. " unless middle_initial.nil?
name += last_name
name
end
end
增加了full_name
方法的User
類
直接將代碼拷貝到這裏肯定是行不通的,@user
變量在User
類中不存在。我們需要把它去掉,因爲這是一個實例方法,當前操作的對象就是這個用戶本身。
檢查重構是否正確。
該在頁面中調用full_name
方法來替代之前的那三行代碼。下面是修改後的列表頁面代碼。
<a href="<%= user_path(user) %>">
<%= user.full_name %>
</a>
使用full_name
的列表頁面代碼。
代碼依然還有提升的空間,創建超鏈接的<a>標籤使用起來太麻煩,可以被Rails提供的link_to
方法替代。
<%= link_to user.full_name, user_path(user) %>
使用了link_to
方法的列表頁面。
這樣一來,頁面代碼是否變得清爽多了?我們去掉了冗餘代碼,又把本應該由模型負責的邏輯移到適當的位置。其實還有優化的餘地,且聽下回分解。
重構之後的代碼
class User < ActiveRecord::Base
def full_name
name = first_name + ' '
name += "#{middle_initial}. " unless middle_initial.nil?
name += last_name
name
end
end
重構後的
User
類。
<h1>Users</h1>
<ul>
<% for user in @users %>
<li><%= link_to user.full_name %></li>
<% end %>
</ul>
重構後的列表頁(
index
)。
<h1>Profile</h1>
<p>Name: <%= @user.full_name %></p>
<%= link_to 'Users List', users_path %>
重構後的用戶資料頁(show
)。
作者授權:Your welcome to post the translated text on your blog
as well if the episode is free(not Pro). I just ask that you post a link back to the original episode on railscasts.com.
原文鏈接:http://railscasts.com/episodes/10-refactoring-user-name-part-1