Previously I wrote about the single responsibility principle. This post will be a continuation of explaining the SOLID principles in terms of functional programming.
Software entities should be open for extension, but closed for modification.
As I mentioned in my previous post, we should always keep in mind that the code will most likely have to change, and we need to expect that. A single change in the code should not result in the need to change other parts of the program. That would be bad design, as it makes the program fragile, unpredictable and unreusable. This concept is not only for OOP but it applies to FP too.
If you were adhering to the single responsibility principle, it will make it a bit easier to apply the OCP. Uncle Bob states that OCP is the foundation for building code that is maintainable and reusable. The main concept behind OCP is that your module should be open to extension as the requirements change, but still be closed for modification. To reiterate in other words you should be able to add new feature to your code as the business needs, without making any changes to the original code.
You might be wondering how we can achieve this, as it seems like the only way to add new features to the program is to change the module. But there is a way!
How we can make this happen is through abstractions and polymorphism.
The code example below is one that I have previously posted before but it explains the concept of open closed very well.
Say our requirement was to make a program that calculates the area of a rectangle and prints that area on to the screen. We would have something like this:
The code above would be just fine if we needed to only calculate the area of a rectangle and nothing else with the concrete knowledge that we will never have any changes. But that is rarely the case. Say we just received another requirement that we need to be able to calculate the area of a circle also. With the current code structure, to make the requirement for calculating the area for a circle, we might end up with something like this:
The above code would be violating the OCP. Adding a new module for a circle makes sense, since we aren't changing anything yet. But where the OCP violation happens is when we modify the existing Printer module. Our code should have been "open for extension" as in adding new functionality, but "closed to modification" as in the original code shouldn't have been edited. As mentioned earlier we can abide by the OCP if we use polymorphism. Polymorphism in Elixir is achieved through Protocols.
Now we should be able to add any new shapes without having to modify the current code.