Favor composition over inheritance

I have take Josh Bloch’s recommendations to heart:

• Item 15 minimize mutability
• Item 16 favor composition over inheritance
• Close/limit the API as much as possible and open/expose it only as necessary
• Design for inheritance and document it or disallow it

I have created very few class inheritance hierarchies over the years – except when I was heavily doing swing/UI work. I used to create lots of abstract classes for common behavior; however, I have since switched to creating interface inheritance hierarchies and utilizing composition. While it is slightly more work except for testing, I can’t recall any particular situation where composition hasn’t worked. However, there are certainly situations where a class inheritance hierarchy is more ideal and I would still favor it over composition.

I have specifically found composition to be excellent for TDD. I can test the parent class fully. Later when I compose, I use a mock and just test the pass-through methods and the new behavior.

If extension were utilized and the parent properties were exposed (broken encapsulation) and utilized, it becomes necessary to inspect the parent and test everything that the extension class touches that is related in any way. If you don’t thoroughly test the extension and someone alters the parent class or some sub-class of the extension, the direct sub-classes very well may break because of the assumptions about the parent class’s behavior with respect to the broken encapsulation. Of course if you break your own encapsulation with getters/setters, which unfortunately is often the case, you gain little or no safety through composition.

I also put final everywhere possible. I prefer to remove final only when I have a very good reason.

If you are ever bored, here is an article on Encapsulation and Inheritance which discusses some of the evils.

Comments

Popular posts from this blog

Sites, Newsletters, and Blogs

Oracle JDBC ReadTimeout QueryTimeout

Locks held on Oracle for hours after sessions abnormally terminated by node failure