tags:

views:

53

answers:

3

I suppose this could go for many OO languages. I'm building my domain objects and am not sure where the best place is for the interfaces & abstract classes.

If I have a pets package with various implementations of the APet abstract class: should it live side-by-side with them or in the parent package?

How about interfaces? It seems like they almost have to live above the implementations in the parent package, since there could potentially be other subpackages which implement it, while there seems to be a stronger correlation between one abstract class and a subpackage.

e.g.

com.foo
com.foo.IConsumer (interface)
com.foo.APet (abstract)
com.foo.pets.Dog extends APet implements IConsumer

OR

com.foo
com.foo.IConsumer (interface)
com.foo.pets.APet (abstract)
com.foo.pets.Dog extends APet implements IConsumer

or something else?

+2  A: 

IMO interfaces and abstract classes are not so different in this respect. It is often better to keep the implementations in a separate package, especially if they are instantiated via a factory. This way these can be kept package private, so their implementation details are better hidden from clients.

So I would go with something like the first choice.

Péter Török
A: 

This is a matter of personal style, but I like (and I've seen others use) a structure where your interfaces and base or final classes are in the package proper, and the implementation classes are in an ".Impl" sub-package. E.g., you'd have a Pets package with Bird, Fish, Mammal and Reptile interfaces, and possibly your base classes that implement those interfaces. Then, you'd have a Pets.Impl package with specific classes for Goldfish, Canary, Collie, whatever. That way, you can give people a Bird and not have to worry that they'll complain that it doesn't lay golden eggs, as that's an implementation detail specific to magic geese. :)

TMN
A: 

Abstract classes are tricky, since both of your choices can feel right. I usually decide it based on how much functionality is provided by the Abstract Class. To extend your example:

com.foo.APet (Abstract Class)
com.foo.pets.ADog extends com.foo.APet (Also Abstract)
com.foo.pets.impl.Westie extends ADog (not abstract).

In this case APet is at the top because it provides the capabilities that are common to all pets. ADog is definitely a pet, but contains those things common to all DOGS. Classes in the impl package are produced by a factory or whatever, and specialize based on breed.

Curtis