So you've got yourself a nice clean package structure. You're slowly building up your application organically, adding features here and there, driven by customer demand. releasing early and often, covering all the hip methodologies of the day. Then along comes a client who wants to make changes so drastic that they warrant sub-classing. We'll call this fictional client Acme. Let's say one of the classes to be altered is:
So you make Calculator abstract, or an interface, and you create two sub-classes:
Seems simple enough. Perhaps years from now you'll have quite the collection of client-specific calorie calculators:
But what if calorie calculators aren't the only part of the system that gets commonly personalized for clients? What if you've got a few dozen classes spread out amongst the enormous source tree that have been abstracted and sub-classed like this? That makes it a little tedious to do site-wide client-specific changes. For example, if you needed to work on all the Acme-specific classes, you'd have to search them all out. It might be a little more convenient if you'd started with a structure like this:
This also makes it easier to clean-up the code tree if you ever lose Acme as a client. You simply delete the root of the Acme-specific classes and presto, all gone. However, it makes it tricky to alter the abstract super-classes when you need to review and test all the sub-classes to ensure nothing broke; you have to search them all out rather than have them all conveniently right there in a single sub-package.
My current project is nearly five years old and contains over three-thousand classes in over six-hundred packages. Over the years we've used both of the techniques described above. And, as I explained, both have their drawbacks.
I'm curious to hear your opinions on the issue.