Two More Principles: the Open Closed & Liskov Substitution
Over the last couple of days at [my apprenticeship](http://www.8thlight.com/apprenticeship) I’ve been reading up on two more of the SOLID principles. The first is the Open Closed Principle, which many of us heard Uncle Bob discuss at last Friday’s [8th Light University](http://university.8thlight.com). In as few words as possible, the open closed principle states that a software method/class/module should be open for extension but closed for modification.
My favorite example of this was one he discussed on Friday of an old phone system that only took ROM chips that had to be manually inserted, and by virtue of ROM being read-only-memory, the program written to the initial ROM chip had to be robust enough that future modifications could just be “plugged-in” as additional ROM chips. As a more recent example, in rewriting my tic-tac-toe application considering the OCP has caused me to think a lot about the structure of my app and how it might need to be extended in the future. I’m currently only allowing the human player to go first and to only play “X’s"— what if at some point the computer needs to go first or the player needs to be allowed to "O’s” or some other character?
Of course, all of those what-if’s can lead to a lot of unnecessary pre-optimization, and that’s where experience and the agile process come into play. If this tic-tac-toe app was for a customer then I could nail down the requirements and ask them if the symbol or order of the player mattered (in this case I’ll be asking [Mike](http://twitter.com/mjansen401) today during our morning meeting). I really like the recommendation about pre-optimization that the PPP book recommends, and that’s to get the “bullets” flying at your app as early as possible (through quick iterations to your customer so that they can provide feedback)- and if that first bullet finds you, then optimize so that it doesn’t happen again.
The principle that I read about yesterday was the Liskov Substitution Principle, introduced in 1987 by Barbara Liskov. The LSP states that a derivative must be substitutable for it’s base. So if “subclassA” inherits from “ClassA”, and classA is passed to a method, then if I pass subclassA to that same method I should expect the same behavior. I’ll try and write this in some pseudocode:
if subclassA :: classA
then method(subclassA) should behave the same as method(classA)
“Design by Contract”, a term coined by Bertrand Meyer and used in the Eiffel programming language, stated the rules of substitution further by explicitly stating preconditions and postconditions for routines within a class. Those preconditions and postconditions had to be met by a derivative as well, with some, er… conditions. Rather than sloppily paraphrase I’ll quote straight from the book on this one: “A routine redeclaration may only replace the original precondition by one equal or weaker, and the original postcondition by one equal or stronger.” (p. 117)
Both of these principles, as well as the Single Responsibility Principle, have seemed to sink in pretty well, but maybe a little too well. As I TDD my way through the tic-tac-toe app I find myself suffering from a bit of paralysis by analysis as I try and consider the principles and think about design smells that might start emanating from my code. I think today I just need to barrel forward and let the bullets start flying.