Designed vs. Open Inheritance
I like Martin Fowler’s write up on Designed Inheritance, but I’m not so sure I agree with his implied suggestion that you cannot have designed inheritance and provide an enabling design.
If I have a component that is being called by other code, and that component is implemented as an abstract class that only allows subclasses to implement abstract methods (all concrete methods are final), then I cannot override the behavior of the parent class. This is designed inheritance because people can only subclass it in the way that I’ve designed. I wrote about this a few years ago when I talked about extending non-abstract classes.
To make this design “enabling” I can simply provide an interface for my component (above the abstract class), and make all the code that references the component point to the interface instead. Now, if I am developing a library and somebody decides that they want to extend it in a way that I didn’t anticipate, they can do so, they just have to implement the interface from scratch. They are free to do it, they just can’t misuse my implementation by using it in a way that it wasn’t designed to be used. I think its fair to have to go out of your way to provide an alternative implementation. Essentially, I’m saying that the framework provides open inheritance, but the implementation provides designed inheritance.
You only really have to worry about unanticipated uses if you’re writing a library anyways. If your writing code within an application, then I would stick to the designed inheritance and let people refactor and change the code if the requirements drive them to that. This is another perspective that I think Fowler didn’t address. I believe that Josh Bloch’s advice is probably geared more towards application developers, while Eliotte Rusty Harold’s comments are within the context of library development. These are different beasts. When you’re contributing to an application, you can change the code, when you’re using a library, you typically can’t.