Open Closed Principle

October 20, 2020

Open Closed Principle

Programming


Title: SOLID Principles in C# – Open Closed Principle
By: Marinko Spasojevic
CodeMaze – Information
Description: Quick coverage of the open closed principle for programming with C# examples.


Overview

“The Open Closed Principle (OCP) is the SOLID principle which states that the software entities (classes or methods) should be open for extension but closed for modification.” This basically means it is preferable to write code in such a way that when a change or extension is suggested for that original class that it can be done through addition instead of modifying the existing class itself. Many of the examples shown do this by adding new classes to handle the additional functionality required instead of modifying the original classes created.

Example #1 – Salary Calculator

The first example they cover somewhat resemebles the factory pattern tutorial I was checking out recently that introduced me to the open closed principle. In this example, they initially create a single class to handle everything. It has a constructor to take in all the members having their salaries taken into accoutn, and then it has a single method handling all the logic of summing all their salaries. As soon as a request for a modification comes in, that single large method within the only class must be edited to accomodate for the new special cases, which clearly violates the Open Closed Principle.

Their suggested revision of the project is what resembles the factory pattern example I was checking out. Instead of just creating the singular SalaryCalculator class, they create an abstract BaseSalaryCalculator class. Next each salary case is broken down into its own class which inherits from this BaseSalaryCalculator class, and these classes internalize all the logic for calculating their salaries so they can individually deal with the differences. Using this approach, if any new options or exceptions need to be accounted for, a new small class inheriting from that BaseSalaryCalculator class can be made without editing any of the existing classes.

Example #2 – Filtering Lists of Computer Monitors

This example provided a list of computer monitors that each had a name, a monitor type, and a screen type. They then needed to be able to filter the list of computer monitors based on the type of monitor. To do so they made a single MonitorFilter class which used a method to filter out the monitors of that specific type and return a list of them. Later they need to add functionality to filter by screen type as well. They accomplish this by adding another method to the existing MonitorFilter class, which again violated the OCP.

Their OCP solution follows a similar idea to the first example, except instead of breaking it down to an abstract class that is then used for several smaller classes with their own logic they use interfaces instead. They create two interfaces, ISpecification and IFilter. The original MonitorFilter class is modified so that it can implement the IFilter interface and is made to be more generic. ISpecification is the interface implemented for the various classes to fit the various filter requests.

MonitorTypeSpecification implements the ISpecification interface and has a constructor that just sets an internal monitor type so that its internal isSatisfied bool method returns true if it matches the monitor type passed in. This is then used in conjunction with the new flexible filter class that creates a list of objects of only those that satisfy the isSatisfied bool within the ISpecification implementing class. Later for the screen type filtering case they create a separate ScreenSpecification class which again implements the ISpecification interface. The only difference in this class is that the Scree enumerator is used and set with the constructor as opposed to the MonitorType enumerator.

Noted Benefits

When working with an already proven and tested system, extending it reduces the likelihood of impacting the full system as opposed to modifying it. Avoiding modifying the original class significantly reduces the chance of changing something that other parts of the system rely on. Extending this way also makes testing easier as it is more likely the new feature can be isolated in testing with this approach, where as modifying the original class likely means that testing of originally tested features may need to be done again since it was more directly modified.

Summary

OCP is a nice philosophy to follow when possible and is extremely applicable to game development projects. Features are modified and added constantly in the game development process, so using an approach like this could prove very beneficial for cleanly and efficiently dealing with the everchaning project. As someone interested in procedural content generation as well, this concept seems very applicable dealing with all the varied but similar features one would encounter with that type of content.