【发布时间】:2013-06-09 19:44:04
【问题描述】:
TL;DR
我需要一种方法来重构包含多个对象和一些复杂数据的复杂用户仪表板,以显示会计图表。我的模型和控制器很乱,所以如果有人有一些提示或建议,我真的很感激:)!
长版:
我目前正在开发一个帮助用户协调晚餐俱乐部和所有相关会计的应用程序。 (晚餐俱乐部是一群人,轮流为剩下的人做饭,然后你支付少量费用参加。这在我所在的宿舍和大学里很正常)。当您登录时,您会看到一个仪表板,其中包含所有重要信息,分为三个部分:下一次晚餐和注册选项、下一次您必须做饭的晚餐以及当前债务、支出等会计概览。
这变得非常混乱:我的控制器中有很多实例变量,还有很多方法可以在我的模型中呈现这个视图。
现在回到真正的问题:谁能告诉我任何好的提示、设计模式或一般建议来帮助我重构这段代码?我已经阅读了有关演示者、服务对象、装饰器等的信息,但我不确定要使用哪个以及如何使用?
这里有一些现在看起来有多糟糕的例子(厨房是一群人一起吃晚饭):
# app/controllers/dashboard_controller.rb
def index
@user = current_user
@kitchen = @user.kitchen
@upcoming_dinner_clubs = @user.upcoming_dinner_clubs # The next dinner clubs where the current user have to cook
@users_next_dinner_club = @user.next_dinner_club # The first of upcoming_dinner_clubs
@unpriced_dinner_clubs = @user.unpriced_dinner_clubs # Old dinner clubs where the user haven't specified a price yet
# The next dinner club in the kitchen
@next_dinner_club = @kitchen.next_dinner_club if @kitchen.next_dinner_club
@todays_dinner_club = @next_dinner_club if @next_dinner_club && @next_dinner_club.date.today?
end
下面的视图显示了一些用户支出和支出的图表,通过 javascript 呈现。我的观点是不正确的。
# app/views/dashboard/_expenses.html.haml
%h2 Dit forbrug
%p
= t '.usage_html', expenses: number_to_currency(@user.last_month_expenses), spendings: number_to_currency(@user.last_month_spendings), results: number_to_currency(@user.last_month_results)
= content_tag :div, "", id: "revenue_chart", class: "chart dashboard-chart", data: { chart: @user.usage_chart_data }
= t '.results_html', results: number_to_currency(@user.total_results)
= content_tag :div, "", id: "result_chart", class: "chart dashboard-chart", data: { chart: @user.result_chart_data }
不想让您对所有细节以及方法的工作方式感到厌烦,但这是我拥有的方法,仅用于在视图中显示费用和支出数据:
# app/models/user.rb
def last_month_expenses
expenses_for((1.month + 1.day).ago, 1.day.ago)
end
def last_month_spendings
spendings_for((1.month + 1.day).ago, 1.day.ago)
end
def last_month_results
results_for((1.month + 1.day).ago, 1.day.ago)
end
def spendings_for(start_date, end_date, kitchen)
end
def expenses_for(start_date, end_date, kitchen)
end
def fee_for(start_date, end_date, kitchen)
end
def accounting_query_conditions(start_date, end_date, kitchen)
{date: start_date..end_date, kitchen_id: kitchen.id}
end
def results_for(start_date, end_date)
spendings_for(start_date, end_date) - expenses_for(start_date, end_date)
end
def total_fee(date = Date.today, kitchen = primary_kitchen)
end
def total_spendings(date = Date.today, kitchen = primary_kitchen)
end
def total_used_on_dinner_clubs(date = Date.today, kitchen = primary_kitchen)
end
def total_expenses(date = Date.today, kitchen = primary_kitchen)
end
def total_results(date = Date.today, kitchen = primary_kitchen)
total_expenses(date, kitchen) - total_spendings(date, kitchen)
end
【问题讨论】:
-
不要;你不使用装饰器/演示器吗?
-
不,但我绝对应该:D!但是我不确定如何以最好的方式实现这一点,我认为上面的例子是一个很好的用例来学习它:)。
-
实际上,从您在那里编写的代码中,我看不出装饰器中没有什么可以抽象的。我也没有看到任何糟糕的设计。您在对象中的方法是有意义的,并且代码非常易读。您在控制器中的实例变量中抽象了很多数据(我不会这样做),但为什么不...
-
你会怎么做?将方法调用链接到用户?
-
是的,就像你写
@user.last_month_expenses时所做的一样
标签: ruby-on-rails ruby-on-rails-3 design-patterns refactoring