|
The next leg of our quest to uncover the deeper driving forces behind SOLID principles brings us to the Open/Closed Principal (OCP). To refresh, I think it's important that if we're going to say (read the next part in a mouth-breathing, war-hammer-playing, mega-nerd voice) "your design violates TLA," we had better back it up with some solid reasoning. Most blog posts focus on the what and how . On this tip there are some great resources out there already. I've even blogged about a technique for achieving OCP with template method and chain-of-responsibility. No matter; we're here to focus on the why ! Without further explanation, let's take a look at... The Open/Closed Principle OCP, as introduced by Bertrand Meyer , states: Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. Once we've decided and are satisfied with the cohesive responsibilities of our class , we want that responsibility to remain stable. Stability is a big, big deal. It allows us to keep forward motion and focus on adding new and interesting behavior in other places in our system. "The Tortoise & The Hare" fable springs to mind. Proceeding methodically and consistently by investing in the design of our software usually pays dividends in terms of the system's total cost of ownership. Jeremy Miller does a great job of linking SRP with OCP in his recent MSDN article : You'll never reach true Open Closed nirvana, but you can inch much closer by rigorously following the related Single Responsibility Principle: a class should have one, and only one, reason to change. One of the easiest ways to write classes that never have to change is to write classes that only do one thing. This way, a class only needs to be modified if the exact thing that it does needs to change. Behavior inevitably changes. We can inject "hooks" or extensibility points into our classes. This lets us keep our existing classes stable while extending their behavior. In a certain sense we could reword OCP as maintain stability in your designs by providing extension points. Sometimes we want to distribute a library and more-often-than-not our code is broken up into multiple assemblies or packages and shared between teams, customers, and other developers in general. Providing hooks that "open classes to extension" help deal with variation just as it aids internal evolution. This topic hints at the larger subject of API design. OCP in the Dynamic Paradigm It's interesting to think about how these principles in a dynamic language like Ruby, considering you can just open any class anywhere or use various techniques such as the instance_variable_set method or alias to completely modify the behavior of an existing class. Michael Feathers points out, in a comment on Dean Wampler's post about OCP in Ruby, that's something we can't do in static languages: The second problem I have...
|