1

AccountクラスとAccountReportクラスがあるとしましょう。account#showで、アカウントのレポートを表示したいと思います。AccountとAccountReportの両方に、いくつかのパブリックメソッドがあります。次のテクニックのどれが良いですか?

1)アカウントとAccountReportをインスタンス化し、アカウントデータを使用してAccountReportを初期化します。

class AccountsController < ActionController::Base
  def show
    @account = current_user.account
    @account_report = AccountReport.new(@account.orders)

    respond_with(@account)
  end

  # ...
end

2)AccountのインスタンスがAccountReportをインスタンス化し、メソッド呼び出しを委任できるようにします

class Account < ActiveRecord::Base
  attr_reader :account_report

  delegate :method_a, :method_b, :method_c, :method_d, :to => :account_report

  after_initialize :setup_account_report

  def setup_account_report
    @account_report = AccountReport.new(orders)
  end

  # ...
end

オプション2は私にとってよりクリーンなアプローチのようですが、アカウントに多くのメソッドをロードすると、神のクラスのように感じられます。

4

2 に答える 2

2

ええと、私はあなたが両方のオプションを混ぜ合わせなければならないと思います。

ショーのレポートのみを使用する場合は、最初のものが適しています。アカウントのすべての時間レポートを使用する場合は、2番目の方法が適しています。

2つ目では、常にレポートがインスタンス化され、パフォーマンスが低下する可能性があります。

あなたはおそらくこのようなことを試してみるべきです:

class Account < ActiveRecord::Base
  # ...

  @report = nil
  def report
    if @report.nil?
       @report = AccountReport.new(self.orders)
    end
  end

  # ...
end

このソリューションの良い点は、レポートが必要な場合にのみ読み込まれることですが、毎回読み込まれるわけではありません。このソリューションの悪い点は、いくつかの注文を追加すると、レポートが最新にならないことです。

更新: これを改善するために、条件をこれに置き換えることができます

if @report.nil || self.created_at_changed?
于 2013-02-08T01:19:48.500 に答える
0

結合度を低く保つため、最初のオプションが好きです。2番目のオプションは、おそらく不要な方法でAccountとAccountReportを結び付けます。別の種類のレポートを取得するとどうなりますか?アカウントの多くのものを変更する必要があるかもしれませんが、それらは一見無関係に見えるので悲しいことです。

これら2つをサービスオブジェクトで組み合わせ、それをビューに渡すことで、コントローラーのロジック/冗長性を低く抑えることができます。AccountReportingサービスは、これら2つのクラスを組み合わせる背後にあるロジックを処理できます。例:

class AccountReporting
    def initialize(account)
       @account = account
    end
    def report
       AccountReport.new(account.orders)
    end
end

次に、コントローラーで使用するには:

AccountReporting.new(current_user.account)

これは意味がありますか?

于 2013-02-08T02:12:58.350 に答える