2014-03-13 5 views
2

나는 이렇게 상당히 자주 내 코드에서 (내 DI 프레임 워크로 Guice를 사용하는) 것을 발견 :종속성 주입 및 관찰자 패턴

public class SomeObserver implements IObserver { 
    @Inject 
    SomeObserver(IObservable observable) { 
     observable.subscribe(this); 
    } 
    // Snip 
} 
테스트, 지금 요구하고하면이 최근 나에게 발생

최소한 모의 프로그램을 내 프로그램에 전달해야합니다. 이는 반드시 최악의 것은 아니지만 최소한 IObservable 인터페이스에 종속성을 바인딩하는 것에 달려 있습니다. 또 다른 옵션은, 생산,이 작업을 수행하는 것입니다 :

public class SomeModule extends AbstractModule { 
    // snip 

    @Provides 
    protected SomeObserver provideSomeObserver(IObservable observable) { 
     SomeObserver newObject = new SomeObserver(); 
     newObject.subscribe(observable); 
    } 
} 

그런 다음 테스트에서, 나는 심지어 Observable에 대한 참조가 필요가 없습니다. 그러나 생성자를 변경하고 싶다면 모듈도 변경해야합니다 (첫 번째 예제에서는 변경되지 않았습니다).

어느 것이 더 낫습니까? 아니면 더 나은 세 번째 옵션이 있습니까?


업데이트 : 약간의 유스 케이스에 대해 이야기하고 싶습니다.

데이터 소스가 Observable 인 데이터 처리 응용 프로그램을 생각해보십시오. 데이터 소스가 시스템의 다른 부분에 대해 알 필요가 없습니다 (Separation of Concerns). 데이터는 독립적 인 작업을 수행하는 적어도 세 명의 옵저버로 필터링됩니다. 테스트, 문제 분리 등의 이유로 데이터 소스를 스왑 가능 상태로 유지하려는 경우 데이터 소스가 Subscribable<Observer> 인터페이스로 정의한 내용을 구현하기 만하면 .subscribe(this)을 호출하면됩니다.

그런 다음 종속성 주입 및 모듈을 사용하여 배선이 정확히 어떻게되는지를 결정합니다. 이 솔루션을 사용하면 주석을 사용하여 주사를 명확히하기 위해 내가 선택한 경우 decorate 관측 가능을 허용합니다.

필자는 본질적으로 원래 생각했던 배선을 관리하기 위해 종속성 주입을 사용하고 있습니다. ObservationManager을 만들면 약간의 이득을 얻으려면 boilerplate이 많이 보입니다. 그러나 다시, 나는 뭔가를 놓칠지도 모른다.

+0

이벤트 버스는 어떻습니까? – condit

+0

@condit 같은 문제가 발생했다면 이벤트 버스를 조롱하거나 적어도 그것에 대한 참조를 만들어야합니다. 테스트 케이스에서 수동으로 메시지를 전달하는 경우에는 적합하지 않습니다. – durron597

+0

테스트에서 이벤트 버스의 실제 인스턴스를 계속 사용할 수 있습니다. 구아바의'EventBus'를 사용하면 테스트 당 새 인스턴스 (또는 테스트 스위트)를 인스턴스화하고'EventBus '를 사용하는 것만 큼 간단합니다.post'를 생성자 (또는 두 번째 예제의 제공자)에 전달하는 대신에 사용합니다. – moofins

답변

1

당신이 의존성 주입을 오용하고있는 것처럼 보입니다.

이름에서 알 수 있듯이 종속성 삽입은 클래스 종속성을 해결할 때 발생하는 문제를 해결하기위한 것입니다. 그러나 의미 상으로 관찰하고 관찰 할 수있는 것은 서로 의존하지 않는다. 그들은 정말로 의존성으로 취급해서는 안됩니다.

observer-observable relationship을 설정하는 것은 그 자체로는 별도의 작업이므로 이상적으로 observer와 observable에 종속 된 세 번째 엔티티가 있어야하며 두 엔티티 사이에 관계를 설정해야합니다. 이벤트 버스를 사용하는 것은이 경우 꽤 직교 해 보입니다. 구독으로 계속 종결되기 때문에 구독은 어딘가에서 이루어져야합니다.

사실이 경우 모의 객체를 사용하는 것이 이상하다는 사실을 알게 된 것은 종속성으로 사용하려고하는 신호입니다. 의존성이 전혀 아님을 나타냅니다. 클래스에 의해 직접 사용되는 일반적인 종속성의 경우 모의 객체를 제공하는 것이 완벽하게 가능합니다.

+0

답장을 보내 주셔서 감사합니다. 문제를보다 명확하게하기 위해 유스 케이스에 대해 좀 더 업데이트했습니다. Btw, 나는 이벤트 버스를 사용하는 것이 문제에 직각이라는 것에 동의한다. – durron597

+0

@ durron597, 아니요, ObservableManager라는 것을 만드는 것이 깔끔하지 않습니다. Boilerplate는 거의 결과를 얻기 위해 많은 코드를 작성해야한다는 것을 의미합니다. 하지만이 경우 논리를 생성자에서 별도의 클래스로 옮길 수 있습니다. 클래스 정의 외에 여분의 코드가 없으므로, 나는 그 보일러 플레이트를 호출하지 않을 것이다. 사실 이것은 우려의 분리입니다. 또한 관찰자 구독을 구성 할 수있는 중심적인 장소가있어 분명히 찾을 수 있습니다. 현재 디자인에서는 이러한 구독이 전체 코드베이스에 퍼져 있습니다. –