저는 다음과 같은 작은 유형 계층 구조로 작업하고 있으며 슬픈 사파리가없는 다른 세상에서 다른 동물 유형이 존재하지 않는다고 말합니다'family'유형에 대한 일반 API 작성하기
public abstract class Animal {};
public sealed class Dog : Animal {};
public sealed class Cat : Animal {};
public sealed class Turtle : Animal {};
public sealed class Bird : Animal {};
내가 API에 관한 한 유사까지 모든 동물을 치료하고 싶습니다,하지만 분명히 그들은 아래의 상황에서 다르게 조금 응답 : '전혀 걱정 탄력성에 대한 확장에) 아니에요 :
public class AnimalCare {
public void Feed<T> (T pet) where T: Animal;
public T PickUp<T> (PetStore store);
}
처음에는 피드를 넣지 않고 피드를 수행한다는 생각을 푸십시오. (AnimalCare가 내 동물 모델에 대한 뷰이고, 나는 우려의 분리에 대해 꽤 단호하다.) 인수를 위해서 척하는 것은 방문자를 제안 할 것이다. .
public class AnimalCare {
public void Feed<T> (T pet) where T : Animal;
public T PickUp<T> (PetStore store);
public void Feed<Dog> (Dog rover)
{
// dump out alpo, lift toilet seat
}
public void Feed<Turtle> (Turtle franklin)
{
// do turtles eat? let him figure it out himself.
} // ...etc.
public Dog PickUp<Dog> (PetStore store)
{
// get bone, tennis ball, leash
}
public Bird PickUp<Bird> (PetStore store)
{
// make sure not dead, nailed to perch
} // ...etc.
}
등등 : 나는 다음과 같은 일을하면서하지만 제가 정말하고 싶은 것은, 위의 걱정하는 AnimalCare 필요의 API 소비자의 유일한 종류의하자입니다. 제 1 부분 (Feed() 메소드)은 제네릭을 필요로하지 않고 그냥 오버로드하는 것이 좋지만 픽업 (Pickup)에 대한 어색한 구현은 여전히 남아 있습니다 (위의 스케치와 같이 구현할 수 없기 때문에). PickUpDog // PickUpBird 등의 비참한 것입니다. 저는 AnimalCare의 소비자와 그와 비슷한 생각을 가진 친구들이 걱정해야 할 별도의 "보기"를 피하고 싶습니다.
저는 컴포지션 또는 인터페이스 리팩토링에서 특수 클래스 및 기타 기괴한 시도를 중첩시켜 놀았지만 올바르게 만들 수없는 것 같아 막혔습니다. 내가 원하는 것과 같은 것을 할 수있는 깨끗한 방법이 있습니까? 아니면 각 구체적인 동물에 대한 AnimalCare 구현을 사퇴 했습니까? 공장/저장소에 대한
편집
조엘의 요점은 내가 좀 더 생각했다. 대신에 관심있는 방법을 조금 더 합리적이라고 부르 자.
public class AnimalPresentation {
public void Show (Dog dog);
public void Show (Cat cat);
//..etc.
public Animal Get (PetStore store);
}
내가 처음에 생각한 것보다 더 의미가 있었을 것이다. PetStore에서 나올 Animal 유형은 Get이 호출 될 때 알 수 없지만 Get의 일반 구현에서 일단 유형이 결정되면 특정 과부하로 분기됩니다. PetStore의 특정 하위 유형이 최선의 방법일까요? 거기에 당신의 동물이 인터페이스 IAnimal
이
첫째 :
그건 내가 두려워했던거야. 말도 안되는 예제 외에, AnimalCare 클래스 및 다른 클래스의 프레젠테이션 또는 서식 지정 요구 사항에 대한 지식을 Animal 클래스에 제공하지 않아야합니다. 필요한 모든 것은 공개 API의 일부이며 실제로 AnimalCare 클래스에서 구체적인 구현 방법을 찾고있었습니다. –
내 편집을 확인하십시오. AnimalCare에서의 구체적인 구현은 AnimalCare 클래스에 IAnimalCareClient을 상속받은 클래스를 임베드하여 수행 할 수 있습니다. –