What is the open-closed principle (in PHP)
In general, the open-closed principle is a software engineering principle that states that modules should be open for extension but closed for change. That might sound like a contradiction, but looking through examples will make the difference between extension and change, clear.
For PHP, or any other language, the open-closed principle can be applied at many different levels (module, class, function, etc). For example, we can say that a PHP class is closed for change but open for extension or we might say that a PHP function does not conform to this principle and is thus open for change (keep in mind that some code has to be open for change).
What problem does the open-closed principle solve?
Imagine a system in which a single change has multiple consequences. You update a method in a class which is called from many other classes and in turn many more. That single update had a cascading effect. The objective of OCP is to minimize or completely remove the cascading of effects.
If our update doesn't affect other classes, we can be confident that our new functionality doesn't have any unintended side effects.
Suppose we want to build a contact form on our website, we'd like to collect a name and email address. Our first (very simple)
ContactForm class might look like the code below:
render method echo's out the form elements that we need. But how do we update the
render method in the future, when we might want to also collect a telephone number? In it's current form, the
render method is actually open for change, which is not what we want. It should be open for extension but closed for change.
OCP in CakePHP
Let's look at a real world example of OCP, in CakePHP, we'll look at the
CakePHP uses the
It differs from our code in the following respects:
controls method to return the completed form inputs, similar to our
- It is passed the
- It loops through each element, without any limitation to the number of elements.
- It returns the completed output string.
You can call the
controls method as shown below:
The controls method is passed an array of form elements to generate.
Updating our PHP code to comply with the open-closed principle
We'll first clean up our code a little before adding function parameters and a loop for our elements.
We've now prepared our code to make it easier for us to comply with the open-closed principle.
render method can now accept an arbitrary number of input elements and render them out. But what happens if we pass a type 'unknown' to it, will that render valid HTML?
We need to update
FormInput to check for valid types.
We can be confident our
render method only returns valid HTML and it is consistent with the open-closed principle. Is the
FormInput class itself open for extension and closed for change?
How do we add new
The below are two possible solutions:
validTypes, like a password or telephone number?
validTypes in a configuration table in a separate file.
validTypes in a different static class.
- Implementing the open-closed principle will give you the confidence to make updates knowing that there aren't any cascading effects because of your changes.
- We've seen an example of the open-closed principle in CakePHP and how we go about implementing it ourselves.
- The open-closed principle in PHP can be applied at the class and function level, have you applied the same principle at any other level?
This article is part of a series on SOLID in PHP, the next article is The Liskov Substitution Principle, the previous article is The Single Responsibility Principle.