Friday, August 17, 2012

Open / Close principle and Design Patterns



The open/ closed principle represents the second principle of SOLID design, in this post I will give an overview of this principle and how to achieve it using different design patterns (including some notes about the limits of each solution) then I will present a different way of achieving it using a less known pattern which is the marker interface combined with some dependency injection and auto-wiring.

The open/closed principle can be summarized by:
“Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.” Uncle Bob
As mentioned in an earlier post, good software is a software that can be adapted to a change easily. Change in requirement or functionality happen quiet often during the life of the software. Its ability to change and adapt to fulfill the new requirements is the key for its success otherwise the cost of maintenance and support as time goes by can cause its  death or even the death of the company (specially if it is a startup with limited resources).

The goal of this principle is to avoid cascading changes every time that we add a small change, making the chances to breaking existing code much smaller. Open for extension means that we can change the behaviour and extend the functionality of the module. Close for modifications means that the module can be changed but without touching the source code. At first look, this seems awkward, how can we change the functionality without touching the code?
This can be achieved using some known behavioural design patterns. I should note that it is hard to apply OCP at 100 % but at least we can make our code extensible and resilient for a certain type of changes, this depends on the context (TDD helps identifying these changes during the iterative process, more on this in a later post dedicated to TDD and how/when to apply design patterns ).

Traditional solutions:

Strategy Pattern:


This pattern is well documented and well known, the main idea is to separate the abstract generic algorithm from its implementation this allows a decoupling between the functionality (behaviour) and the class that uses the behaviour. This way we can add more functionality by implementing the Strategy interface then tell the context to use it.

Notes and limitations:

-I have seen some examples in books where they implement a method in the context to choose the strategy to use, depending on the context, personally if the choice of the strategy is a configuration concern i try to avoid this way since it implies some changes to the context and it can lead to many if-else statements which i hate, as alternative i like to push this responsibility to IOC container like structure map since he is responsible for managing the creation and the life cycle of  objects, this always depends on the context, for example if the selection of the right strategy depends on some internal processing inside the context then placing a method that choose the strategy inside the context makes sense but i always try to avoid if statements with some fashion :P).
-If the concrete strategies contains only one method they can be replaced by delegates instead of classes.
-I think we should pay attention when using Strategy pattern specially on how we select the strategy to use. If  the selection is inside the context class and each time we add a strategy we must change the code in the context than it is still open for modification and breaks the OCP.

Visitor Pattern:



In short, the visitor pattern allows to add functionality to classes without modifying them by implementing a class (visitor) that contains different implementations of the desired functionality.

Notes and limitations:

-It is clear that the visitor pattern fits well to OCP but in my point of view it is against POO encapsulation primciple which consists in encapsulating data and methods manipulating that data in the same class, but it is a trade off between adding a method for each element every time we need to add a functionality to a hierarchy or just derive a class from the visitor.
- Another drawback is that we need to add a visit method for each derived visitor class each time we add an element, which means all classes will be open for modification each time we derive from Element.

There is other patterns that helps to apply OCP like decorator, chain of responsibility, ...

Summary

For this post i tried to focus more on the limitations and drwabacks of each pattern as i think it is essential in order to make a good use. Design patterns are not magic they should be well understood and used carefully otherwise it would result in an over-complicated software, i will dedicate a post on how to use design patterns, their relatioin with TDD process.

For the next post i will write about a less known solution but very powerful based on marker interface with DI and Pub/Sub pattern (my favourite solution).
Stay tuned :)

Thursday, August 9, 2012

D.R.Y principle and the Broken clock




This will be a short post, it is more like taking note of a thought that crossed my mind.







         VS






 
Dry: Don't repeat yourself principle, a well known and preached principle.
We should pay attention how to apply "Dryness".
Depending on the context, for example the source code for create and update may be identical in many scenarios but at sometime the logic may change and they can be different, if you try to apply dry by trying to use the same code base for the two operations this can catch you later. they are the same by accident, but will likely vary by design later and should therefore not share code in common.


Remember: even a broken clock is right twice per day. (but it is still broken)

:)