I'm working with a smallish type hierarchy, something like the following, and lets say there won't ever be any other Animal types in my sad safari-less world (I'm not at all worried about resilience to expanding):
public abstract class Animal {};
public sealed class Dog : Animal {};
public sealed class Cat : Animal {};
public sealed class Turtle : Animal {};
public sealed class Bird : Animal {};
I'd like to treat all of the animals similarly as far as the API is concerned, but obviously they respond just a little differently in the below situations:
public class AnimalCare {
public void Feed<T> (T pet) where T: Animal;
public T PickUp<T> (PetStore store);
}
At first blush the idea of performing feedings without putting a feed method on the Animal class (sorry, I know the example is reaching at this point, but lets pretend for the sake of argument that AnimalCare is the view to my Animal models and I'm pretty adamant about separation of concerns) would suggest a visitor. But what I would really like to do is let the above be the only sort of API consumers of AnimalCare need to worry about, while I do something like the following:
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.
}
And so on. I know the first part (the Feed () methods) are fine to just overload without even needing generics, but that still leaves me with an awkward implementation for PickUp (since its not legal to implement as I've sketched it above), something miserable like PickUpDog//PickUpBird etc. I would very much like to avoid having a separate "view" for consumers of AnimalCare and its like-minded friends to have to be concerned with.
I've been playing around with nesting specialized classes and other bizarre attempts at composition or interface refactoring, but I can't seem to get it right and I'm stuck. Is there a clean way to do something like what I want, or am I resigned to implementing an AnimalCare for each concrete Animal?
EDIT
Joel's point about factory/repository made me think some more. Let's instead call the methods of interest a little more reasonable:
public class AnimalPresentation {
public void Show (Dog dog);
public void Show (Cat cat);
//..etc.
public Animal Get (PetStore store);
}
That would have made more sense in the first place I suppose. The type of Animal to be gotten out of PetStore isn't known at the time Get is called, but in the general implementation of Get, once the type is determined, it branches to the specific overload. Is specific subtypes of PetStore the best/only way forward here?