2013-02-08 8 views
1

계정 클래스와 AccountReport 클래스가 있다고 가정 해 보겠습니다. accounts # show 계정에 대한 보고서를 보여주고 싶습니다. Account와 AccountReport는 여러 가지 public 메소드를 가지고 있습니다. 뒤에 오는 기술의 어느 기술이 더 낫습니까?추가 클래스를 위임하거나 인스턴스화 하시겠습니까?

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) 계정의 인스턴스 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

음, 두 가지 옵션을 혼합해야한다고 생각합니다.

첫 번째 보고서는 보고서 만 사용하는 경우 유용합니다. 두 번째 계정은 모든 시간 보고서를 계정에 사용하는 경우 유용합니다.

언제든지 보고서가 인스턴스화되고 성능이 저하 될 수 있습니다.

당신은 아마 이런 식으로 뭔가를 시도해야합니다 :

class Account < ActiveRecord::Base 
    # ... 

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

    # ... 
end 

이 솔루션의 좋은 점은 필요한 경우 해당 보고서는로드,하지만 때마다로드되지 않습니다. 이 솔루션의 나쁜 점은 일부 주문을 추가하면 보고서가 최신 상태가 아닐 수 있다는 것입니다.

UPDATE : 이를 개선하기 위해, 당신이 낮은 커플 링을 유지하기 때문에 나는 첫 번째 옵션을 좋아하는이 하나

if @report.nil || self.created_at_changed? 
+0

나는 그것을 얻는다 고 생각한다. 나는 보고서를 느리게로드한다는 생각을 좋아합니다. 이런 식으로 AccountReport/Report에 위임 할 수 있습니까? 아니면이 방법으로 account.report.total 메서드 체인을 사용해야합니까? –

+0

'@report || = AccountReport.new (self.orders)'는 위에서 뭘 하려는지에 대한 훌륭한 은유입니다. –

+0

감사합니다. 나는이 두 가지 조언을 결합하여 아름답게 작동하고 있습니다. 나는 독자를 버렸고, 보고서를 얻고 그곳에서 보고서를 반환하거나 초기화하는 방법을 썼다. –

0

과 조건을 대체 할 수 있습니다. 두 번째 옵션은 Account와 AccountReport를 아마도 불필요한 방식으로 연결합니다. 다른 유형의 보고서를받을 때마다 어떤 일이 발생합니까? 계정에서 많은 것들을 변경해야 할 것입니다. 계정은 겉으로보기에는 관계가 없기 때문에 슬픈 일입니다.

서비스 개체에서이 두 가지를 결합하여 컨트롤러에서 논리/자세한 정보를 낮게 유지하고 뷰에 전달할 수 있습니다.

AccountReporting.new(current_user.account) 

이 메이크업 감각을합니까 :는 AccountReporting 서비스는이 두 가지 클래스를 결합 뒤에 논리, 예컨대이 :

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

그런 다음 컨트롤러에서 사용하는 처리 할 수 ​​있습니까?

+0

흥미 롭습니다. 이것이 유용 할 곳을 알 수있었습니다.나는 자주 사용되는 클래스에 대해 # 2 접근법의 세련된 버전을 사용할 수 있다고 생각합니다. 자주 사용하지 않는 클래스의 경우이 접근 방식 (향상된 # 1)을 사용할 수 있습니다. 당신은 제가 이런 종류의 수업을 여러 개 가지게 될지에 대해서 알았습니다. 더 나은 SRP/디커플링을 위해 내 응용 프로그램의 두 가지 클래스를 껍질을 벗기려고합니다. –

관련 문제