"The idea was that once completed, the implementation of a class could only be modified to correct errors; new or changed features would require that a different class be created."
This sounds a lot like bolt-on coding, always adding code rather than assimilating new features into a codebase. This doesn't seem like a sustainable strategy at all. Yes you don't risk breaking any existing functionality but then why not just use a test suite? The major problem though is that instead of grouping associated functionality into concepts (OO) that are easy to reason about, you are arbitrarily packaging up functionality based upon the time of it's implementation... (subclassing to extend).
> ...you don't risk breaking any existing functionality but
> then why not just use a test suite?
The library programmer can easily distribute the test suite so that the application programmer can run the tests, but that doesn't change the fact that if the library programmer changes an object's interface, it breaks the application programmer's code. By committing to keep the old object's interface intact, the library programmer is giving the application programmer time to migrate their code to the new objects.
For applications I'm not sure open/closed makes as much sense - http://codeofrob.com/entries/my-relationship-with-solid---th...
> For applications I'm not sure open/closed makes as
> much sense.
I'm not sure I agree with Rob Ashton's points, though. In his blog post, Rob trivializes the utility of third-party libraries:
> * These [libraries] are either replicable in a few
> hours work, or easily extended via a pull request.
He also underestimates the amount of time it takes to continuously change application code to keep up with breaking changes from third-party libraries:
> * These [libraries] can be forked for your
> project and changes merged from upstream with
> little effort.