2012-11-26 3 views
2

레일의 조성물에 상속을 변환 : 우리는 하나 개의 상품 진형나는 이런 식으로 뭔가 보이는 레거시 시스템에서 모델이

class Prize < ActiveRecord::Base 

    def win 
    # do a bunch of things 
    end 
end 

,하지만 아무것도 우리가 다루고있는 상품의 종류 등 확장하기 시작했습니다. 그래서 지금은 def win이 모든 종류의 케이스/스위칭을 결정하여 상금 유형을 결정합니다. 이 코드는 검토했다

class DailyPrize < Prize 
    def win 
    #do only daily prize stuff, no type checking. 
    end 
end 

우리가 QA에 퇴장하기 전에 지금 나는이 사용하는 구성 (믹스 인)가 아닌 하위 클래스를하도록 요구하고있다 :

는 이유로 나는이 작업을 수행하기로 결정했다. 나는 이것을 할 수있는 깨끗한 방법을 생각할 수 없다.

레거시 코드베이스

이 장소의 무리에서 다음을 수행하고 내가 사방에 물건을 변경 가고 싶지 않았다

상 =

그래서 prize.win Prize.new , 내 질문이 구성을 사용하여 어떻게 만들 수 있습니까?

+2

저는 컴포지션이 종종 더 나은 선택이라고 생각하지만, 여기에서 사용하는 것에 대한 논쟁은 무엇입니까? - 당신이 보여주지 않은 상속 수준이 더 있습니까? 또한 STI를 사용하고 있습니까? 일반적인 방법을 사용하면 공통 하위 클래스가 필요합니다. 나는 "나는 그런 식으로 해달라는 요청을 받았습니다"라고 혼란스러워합니다 - 리뷰를하는 사람이 당신을 납득시키지 않고 (그리고 더 잘 할 수있는 방법을 보여주었습니다)? – averell

+0

응답 해 주셔서 감사합니다. 나는 왜 내가 작곡을 사용해서 그것을해야만하는지에 대한 이유를 알지 못했지만 그것이 일어나도록하기 위해서입니다. 어젯밤에 타입 컬럼을 추가했고 STI를 사용할 것입니다. 상속의 수준은 단순히 두 가지입니다 : 상금과 그것의 아이들. – RidingRails

답변

0

내가 생각할 수있는 한 가지 방법은 특정 상품을 모듈 (예 :

module DailyPrize 
    def specific_method_1 
    end 

    def specific_method_2 
    end 
end 

... 그리고이 같은 상 클래스 갖는

class Prize 
    def win 
    # do something in common 
    specific_method_1 
    # do something in common 
    specific_method_2 
    # ... 
    end 
end 

을 그리고 당신이 선택으로 클래스를 인스턴스화 할 때 당신은

def initialize (prize_type) 
    # mixin the appropriate module 
end 
+0

Matko에 감사드립니다. – RidingRails

2

여기 예를 들어, 모듈을 믹스 인 할 수 있습니다 상속에 대한 구성으로 코드를 대체하여 이해하는 것입니다.

class Prize < ActiveRecord::Base 

    def prize 
    @prize ||= PrizeFactory.build(self) 
    end 

    def win 
    prize.win 
    end 
end 

class PrizeFactory 
    def self.build(prize) 
    if prize.daily? 
     DailyPrize.new(prize) 
    # other condition to build specific prize 
    end 
    end 
end 


class DailyPrize 
    def initialize(prize) 
    @prize = prize 
    end 

    def win 
    #do only daily prize stuff 
    #access @prize to get @prize attribute 
    #if you use it, you have coupling (see below) 
    end 
end 

사실이 것은 구현보다 좋지 않을 수 있습니다. 이것은 도메인 논리의 관점에서 달성 한 결과에 따라 달라집니다. 구성으로

는 하나 개의 목표는 당신이 DailyPricewin 방법 @prize 객체 메소드를 많이 호출하는 경우,이 두 클래스 간의 밀접한 결합이 있고 구성의 이점을 상실 할 수있다, 객체 사이의 커플 링을 줄이는 것입니다 .

관련 문제