2011-04-06 3 views
1

나는 다음과 같은 상속 구조가 상상 : 내 응용 프로그램 클래스에서위치 의존성 (전략, 저장소 등)

AnimalsNamespace.Animal 
CatsNamespace.Cat : Animal 
DogsNamespace.Dog : Animal 

을, 나 자신이 다음 코드 유형을 많이 직면 찾을 :

void Feed(Animal animal) 
{ 
    if (animal is Cat) 
    { 
     KernelContainer.Get<ICatFeedingStrategy>().Feed((Cat)animal); 
    } 
    else if (animal is Dog) 
    { 
     KernelContainer.Get<IDogFeedingStrategy>().Feed((Dog)animal); 
    } 
} 

잠시 동안 괜찮지 만,이 if 문을 뒤에서 추적 할 수 있습니다. 나는 또한 당신이 그들의 타입 등을 요구할 때 이상하게 행동하는 NHibernate 프록시에 문제를 얻는 것을 시작하고 모든 것들이 혼란에 빠지게된다.

나는 공장 클래스를 만들 수 있지만, 난 그냥 고양이 먹이로 내가 가지고있는 복잡성의 전체 힙으로 끝낼 : ICatFeedingStrategy, ConcreteCatFeedingStrategy, IAnimalFeedingStrategyFactory, ConcreteAnimalFeedingStrategyFactory (플러스 종종 추상 기본 클래스를 AnimalFeedingStrategyBase와 같은).

이러한 상속 구조를보다 효율적으로 관리 할 수있는 패턴이 있습니까?

답변

0

지금 당신은 인터페이스에 대해 프로그래밍을해야하는 구체적인 클래스에 대해 프로그래밍하고 있습니다.

위의 예는 using an Abstract Factory to resolve dependencies based on run-time information으로 처리 될 수 있습니다. 이제 피드 방법은 다음과 같습니다

void Feed(Animal animal) 
{ 
    var strategy = this.factory.GetFeedingStrategy(animal); 
    strategy.Feed(animal); 
} 

factory가 주입 IFeedingStrategyFactory입니다. 당신이 알려진 아형의 유한 목록이있는 경우

또 다른 옵션은,의 Visitor pattern을 사용하는 것입니다.

+0

반대로, 제 예제는 인터페이스로 채워져 있습니다. 또한 나는 네 번째 단락에서 공장을 언급했다. – cbp

+1

Abstract 팩토리는 복수의'if' -s- – yegor256

+0

@ yegor256의 사용을 제거하지 못합니다. 그러나 코드가 여러 개있는 경우에는 코드를 멀리 옮깁니다. – Marcus

0

아마도 chain of responsibility이 도움이 될 수 있습니다. 첫째, 모든 "피더"가 체인에 등록됩니다. 그런 다음 feed()은 체인에서 첫 번째 "피더"를 호출합니다. 모든 피더는 자체 하위 클래스를 먹이는 방법을 알고 있습니다. 여전히 if -s가 많지만 관련 하위 클래스와 밀접하게 관련되어 있습니다.