[英]How to refactor a large Ruby class?
我有一個足夠大的控制器類,這是一種不好的做法(Rubocop發出此警告:類定義太長)。
該類有許多私有方法,所有這些方法都會計算要重定向到的路徑,因此這是控制器問題。
如何重構?
示例代碼:
class PostController
def new
@post = Post.new
end
def create
@post = Post.new(post_params)
# ...
end
# more resources methods
private
def post_params
# ...
end
def post_url(post)
if params['submit-save'] || params['submit-publish']
url_for [:edit, post]
else
url_for [:review, post]
end
end
def next_post_url(post)
next_post = post.find_next
if next_post
url_for [:edit, post]
else
some_path(next_post)
end
end
# some more methods
end
通過對您的問題的討論,我的想法是確定正在計算重定向路徑的各種私有方法是否可以屬於特殊目的的類,該類抽象了路徑計算邏輯的各個方面,或者可能僅僅是控制器混合使用的模塊正確的答案將在很大程度上取決於您的邏輯在各種私有方法中的模樣。 一個簡單的模塊不太可能是正確的方法,因為您只是將代碼移到其他地方以滿足任意度量標准。 確定所有私有方法的原因並提出更好的抽象可能是正確的方法,但是可能會發揮不同的作用。
本文討論的許多相同模式都將適用於超重控制器和模型: 重構Fat ActiveRecord模型的7種模式
因此,從評論中提取結論,我喜歡這兩個想法:
我同意,最后的話將永遠來自開發人員,但是如果您添加諸如rubocop之類的工具是為了鼓勵您編寫更好的代碼,那么對我來說,添加rubocop然后禁用一些檢查是沒有意義的。
我也不會使用輔助方法,原因是一類應該只承擔一種責任,所以它應該只具有一種行為。 人們傾向於將各種類型的方法放入助手中,這些方法具有完全不同的行為,從而賦予該類許多不同的責任。 如果它的所有方法只有一個目的,那么我只會使用一個助手。
在您的特定情況下,我會更傾向於將知識提取到簡單的類中。 嘗試識別不同的行為並將其封裝到類中。
在這種情況下,您似乎擁有某種url構建器,因此可行的解決方案可能是:
class PostController
def new
@post = Post.new
end
def create
@post = Post.new(url_builder.post_url)
# ...
end
# more resources methods
private
def url_builder
UrlBuilder.new(self, params)
end
end
class UrlBuilder
def initialize(self, params)
@self = self
@params = params
end
def post_url(post)
if params['submit-save'] || params['submit-publish']
self.url_for [:edit, post]
else
self.url_for [:review, post]
end
end
def next_post_url(post)
next_post = post.find_next
if next_post
self.url_for [:edit, post]
else
some_path(next_post)
end
end
private
attr_reader :self, :params
end
這不是一個完全正常的示例,因為我不知道您的控制器的整個實現,只是一個可能的解決方案,需要進行一些調整。 關於該解決方案,有兩件事要說:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.