Thursday, March 15, 2012

Open/closed Principal (and CQRS)

Five days ago I saw John Teague speak on the Open/closed Principal at the Dallas Day of Dot Net convention. This is the principal asserting that classes should be open for extension and closed for modification. John asserted that OCP was essential to creating maintainable code. In a nutshell, a fat class exposing everything in its guts over public methods should be more modest. Beyond just tucking things away into private methods however, John spoke to how one should just break many internal mechanics of classes out into separate helper classes that another action could not have access to without violating the Law of Demeter. (I once heard Mahendra Mavani suggest this analogy: If I wanted to borrow a dollar from a friend, I would not reach directly into his wallet, I would ask my friend for a dollar, he would go into his wallet himself, and then he would hand me the dollar from his wallet. This sort of abstraction illustrates how some concerns may be tucked away behind logical boundaries in such a way that random access is clearly inappropriate.) John spoke to five patterns:

  1. Template Pattern lets one tuck code away to a base abstract class. The pain point is that one may only inherit from one parent and thus there is the potential for the parent class to grow fat and unmanageable.
  2. Strategy Pattern pulls logic out of a primary class into helper classes. The constructors or other method signatures in the helper classes may feature much polymorphism (overloading) and thus allow for the primary class to blindly hand requests to a helper in such a way that the helper decides by gauging what it is receiving as to what to do with the request. This is a way to get rid of case/switch statements.
  3. Command Pattern allows one to process commands at a class which routes to other classes based upon what is being processed. This is CQRS stuff. CQRS stands for Command Query Responsibilities Segregation. John Teague offered that the fundamental qualification for CQRS was an acknowledgment of a write model different from a read model within a pattern.
  4. Composite Command Pattern involves composing commands as described in the Command Pattern together and getting them to execute without conflict.
  5. Visitor Pattern was tougher for me to understand. I get the impression that in a visitor pattern a class will have a method which visits a method on a different class where the real guts of the logic needed to make a decision will be. A Person might have a LoanDollar method which reaches out to the LoanDollar method on PersonWallet, gets its result, and then hands back the result from the other method as its own result. I think I have this example correct, yet I may be botching this one however. I found this one the trickiest.

In all examples, one class defers some decisions to at least one other different class in the name of keeping classes small.

2 comments:

  1. This may help with the visitor pattern, or at least how I use it, is as an inverted form of the strategy pattern.

    So, in the strategy pattern, you have behavior that is interchangeable on an instance of a class. I.E. Car -> Transmission, switch out shifting methods from auto to manual. (not the best example, but hey.)

    Now, the visitor pattern would be more for algorithmic interchangeability, so for example, switching out a "painter" method which visits each car on the assembly line in a factory (so you pass a list into paintRoom, which has a painter visitor for car).

    ReplyDelete
  2. Oh, ok. That does make sense. So one hands a collection of Foo to FooHelper more-or-less. Is that correct? Thank you for your commentary. I really had it wrong.

    ReplyDelete