SOLID: The Open-Closed principle (OCP)
Open for extension, closed for modification
"You should be able to extend the behavior of a system without having to modify that system."
Just as in the case of the SRP, OCP is about minimizing the impact of changes in your software. Whether we are talking about re-usability within your code or the use of that code by others, it is a great advantage to be able to extend the features of your app without the need of modifying the whole thing.
For example, imagine a feature which sends a notification email every time a new post is published in my blog. With a high level of coupling, I risk sending the notification after post publishing has failed.
How do we accomplish it? Avoiding dependence upon specific implementations. Or better said, by using generic or abstract classes or interfaces that will be later defined in the final classes.
What is the difference between using an interface or an abstract class?
- Interfaces:
- They don't modify the hierarchy tree
- It is possible to implement more than one interface
- It is frequently used to decouple code
- Abstract class
- It allows the use of Template-Method Pattern (pushing the logic of the business to the model). That means defining the header of the functions (making them abstract), defining them later on in the Final Child Class. In essence, it's like creating a Template which will be filled in by the child Final Class.
- It allows following the principle of Tell, don't ask. This method states that, instead of requesting data to the objects, we need to tell them what to do and request the result. For example:
Class User {
private $roles = ["ADMIN", "STUDENT"];
}
Class Login {
If (in_array("ROLE_ADMIN", $this->user->getRoles()) {
return new RedirectResponse($this->urlGenerator->generate(self::ADMIN_ROUTE));
}
}
We would refactor it to TELL pattern as follows:
Class User {
public function isUserAnAdmin()
{
return in_array("ROLE_ADMIN", $this->user->getRoles());
}
}
Class Login {
If ($this->user->isUserAnAdmin()) {
return new RedirectResponse($this->urlGenerator->generate(self::ADMIN_ROUTE));
}
}
- We use it when code is not too complex in order to avoid the need to sort of jump between abstract classes and child classes.
Comments
Post a Comment