Deep Class Hierarchies

DeepClassHierarchies occur when the height of the class hierarchy is longer than its width.

What is the "width" of a class hierarchy? Is it the number of peer children derived from a base class?

Taken from: question 9:

If you reject the use of abstract classes and build deep hierarchies with lots of data defined at each level, you really shouldn't be surprised by long compile times, frequent recompilations, and problems understanding what is defined where. -- BjarneStroustrup

Defining a lot of data (attributes) in a class is condered bad style. DeepClassHierarchies are necessary for good OOD/OOP. That's why I don't like CeePlusPlus. -- GuillermoSchwarz

Why do you think that DeepClassHierarchies are necessary for good OOP? I've usually found that they make understanding and maintenance more difficult.

DeepClassHierarchies are good because every class can be thinner. See the Smalltalk class library. You just need to understand the 10% of the classes in the top of the hierarchy, the rest is just a matter of looking at the source. Do you know any other language like that? Smalltalk is so simple, even Java looks extremely complex in comparison.

Why do you think DeepClassHierarchies make understanding and maintenance more difficult?

What is the definition of thinner? I rarely see a need for more than two levels in a class hierarchy, i.e., an abstract interface class and an implementation class.

When you say good, do you mean good "all considered"? Please list the items on your scorecard. DeleteWhenCooked. -- dl

That question is interesting: What is good OOD/OOP? There are many ideas in PrinciplesOfObjectOrientedDesign, which I share. But I think there is more to it, namely that ClassesShouldBeThin?. I've seen this written somewhere, but I'm sure that was one of the biggest mistakes I made in the past, it was a relief when I divided those in classes in ManySmallClasses? because at that time the code could be easily changed, except that it was too easy to introduce subtle bugs so I independently reinvented UnitTests. So you see, my argument goes like this:

ObjectOrientation => ManyThinClasses? => UnitTests.

Also it would be interesting to automatically run the tests of superclasses on subclasses. If that were not possible, having DeepClassHierarchies would be a disaster; there would be no way to verify the ClassInvariant.

Is there any place where UnitTests are a requisite? I think every ObjectOriented project should heavily use UnitTests, but AFAIK only XPers advocate UnitTests as much as I do. Actually XPers advocate TestDrivenDesign, which is even stronger.

Now going back to your question, why DeepClassHierarchies? I could easily write ManyThinClasses?? and never use inheritance, but unfortunately those classes wouldn't do much. It could be argued that using delegation (ProxyPattern) would solve that problem, and that's probably true, but you would need UnitTests for the code to be usable.

If you believe that inheritance is a good thing, then you should use DeepClassHierarchies, or else do not use inheritance at all. -- GuillermoSchwarz

UnitTests are a good thing, and are not in any way specific to OO techniques.

I agree. If I produce cars, I can test every part individually before assembly. That would be the automotive equivalent to UnitTests. What I'm saying is something different though. I'm saying that if you do proper ObjectOrientation, you need UnitTests. The reason is that having so ManySmallClasses? working together makes the code fragile. UnitTests are a necessary balance.

UnitTests are a good thing whether you use delegation or inheritance. I don't understand the assertion that delegation requires unit tests.

Using a lot of inheritance requires UnitTests. Using a lot of delegation also requires a lot of UnitTests.

If you believe that nails are a good thing, then you should use nailed assemblies. Unless glued or welded ones are better for your application, of course.

Maybe. Either way, I would UnitTests those assemblies.

If you believe that inheritance is a good thing, then you should use DeepClassHierarchies, or else do not use inheritance at all. -- GuillermoSchwarz

This is contrary to the usual advice; why do you say that? I'm not sure if you intended to answer that question already above, but in fact you did not answer it. -- AnonymousDonor

Please be specific about the usual advice.

The justification for DeepClassHierarchies:

1. More use of inheritance. Classes can be thinner if they inherit most of the code. This also is better for OnceAndOnlyOnce.

2. The opposite of DeepClassHierarchies is FatClassHierarchies.

How does PackageDesign affect class hierarchy depth? How many objects per package - is it analogous to ManyShortMethodsPerClass ? -- AnonymousDonor

PackageDesign has nothing to do with DeepClassHierarchies, AFAIK. ManyShortMethodsPerClass is orthogonal to DeepClassHierarchies. -- GuillermoSchwarz

So you just deliver one gargantuan .DLL or EJB implementing the deep class hierarchy? Or thousands of small ones, one for each class?

DLL is just an implementation. You can have one DLL for each class (preferred) or one DLL for several classes. Java made it right by creating exactly one .class for each .java, but of course it would be too hard to use that way, so .jar was invented. It could be argued that .DLL is similar to .jar, but it is easy to open a .jar and see ehat is inside. It is not so easy for a .DLL. oes this have anything to do with DeepClassHierarchies?

EJB is ComponentTechnology?, not ObjectOriented technology. I think I did not understand your question.

The question is how do you partition up the ClassDiagram into packages (irrespective of the technology used to implement it)? Presumably the classes are being designed for an application, the package structure should be part of the design

I would follow the magic number 10: Do not put more than 10 classes in a package. Since you can happily put 100 classes in a package, probably this is not good advice for beginners: First make sure that your packages make sense. They should be stored in jar files and then you will realize that whenever you want to modify your libraries, it is easier to modify if you don't have more than 10 classes per package. I'm not advocating creating BigFatClasses?, but creating more packages to store your classes in a package structure that makes sense to you.

The package structure is not as important as the hierarchy structure. How should you define if the package should contain a class or not? Probably if the class should not be released without the other classes in the package. But there are also subpackages, so maybe that's not the only criteria to apply. I would use that criteria + never put more than 10 classes in a package.

Thanks that is the kind of answer I was hoping for. Now looking at it more practically, if you have say 5000 classes, that means 500 packages. Assume we are using Microsoft as the OS that means 500 .dlls, how does that affect load on the application server? Should interprocess communications between components be considered in how the partition is done when designing?

You can always have subpackages that go in the same DLL. One thing is the number of packages you have and another is the number of DLLs or jars.

And you can have sub-packages within sub-packages (here I am thinking of UML PackageDiagrams? which would contain the ClassDiagrams - and parallel ones for UseCases). Typically the top-level packages would map to deployable components - .DLLs, .jars or whatever. This package structure constrains the class structure even if packages are given less of a priority. Hence the initial statement about needing to consider PackageDesign in conjunction with class hierarchy design.
An interesting article about software structure as ScaleFreeNetworks:
See DoMoreWithLess, ShallowHierarchies

View edit of November 26, 2014 or FindPage with title or text search