The open/closed principle basically values not spoiling what is already ready. That is, think of your preferred programming language, now suppose you have numerous applications developed in that language, however one fine day comes out a newer version of this language and you are forced to go back to fixing all your applications developed so far because the language simply changed the way to do something and did not continue the old way of doing it. Now multiply that by all the developers of that language around the globe. Have you thought about the chaos that this would generate?
In smaller proportions we also develop code that can be used by other classes of ours in other applications or even used by others.
An excellent (simplified) example of avoiding hurting this principle are getters and setters.
Example: You made a code without the getters and setters, however you realized that some of the attributes in your class need a validation, say some date that cannot be defined as before the current date, because in fact it must refer to something in the future. I mean, you shouldn’t allow something like this:
material.dataPrevistaDeChegada = new DateTime("01/01/2014");
To fix this you decide to put the get and set to the date field and change the access from public to private. Doing this all the codes that made the access to the attribute directly will be broken, because it is no longer possible to access the attribute the way it was done before.
However, if the attribute has always been private and always had the get and set nothing prevents you from implementing the value check before changing its date, for this you just need to improve your code without breaking the code of the other classes.
Code example using set without thinking about validation:
public void setDataPrevistaDeChegada(DateTime dataPrevistaDeChegada) {
this.dataPrevistaDeChegada = dataPrevistaDeChegada;
}
Code when you realized that validation was important:
public void setDataPrevistaDeChegada(DateTime dataPrevistaDeChegada) {
if(dataPrevistaDeChegada.isBefore(new DateTime(DateTime.now()))) {
return;
}
this.dataPrevistaDeChegada = dataPrevistaDeChegada;
}
The return
is just an example, if you want you can assign a default value as long as this is acceptable for your application.
In the above example you extended your code, however you didn’t change it. Ok, in practice you made a modification, but this modification is transparent to those who depend on your class, so you can change internal details as long as it doesn’t affect those who depend on your class, this would be called extension rather than change.
By modifying the set, you have ensured that the date attribute will not change if the condition placed inside the set is not met, this example is just a good simplification of how not to hurt the principle, worth being cited for being widely known among developers.
More advanced solutions to ensure the open/closed principle would basically be a more elaborate modeling of its classes, such as the Factory Design Pattern (Factory Design Pattern) which is an intermediate between the class that wants a new class instance and the class that will provide that new object. Inside the Factory you put the rules for creating the object, if one day you need to change these rules you can do without having to modify the classes that depend on it.
Relevant: http://qualityisspeed.blogspot.com.br/2014/08/why-i-dont-teach-solid.html
– Maniero