S.O.L.I.D principle in Unity3D and Game Development-Part 2: Open-Closed Principle(OCP).

Habibur Rahman Ovie
3 min readJan 24, 2021

Open-Closed Principle (OCP) is the Second principle of SOLID. According to Bertrand Meyer Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Robert C. Martin considered this principle as the most important principle of object-oriented design.

Software development is a continuous process and it always evolving by adding new features. But if our codebase is not scaleable then previous codes will break when we adding new features. So for fixing the errors we modify our previous codes and made the code base more vulnerable.OCP solves this problem. The general idea of OCP is Adding new functionality without changing existing code. let's dive into the code for better understanding.

Task Overview: In our game, we have 4 types of collectibles ( Gun, Sword, Pain_Killer, and Energy_Drink). Each item has different behavior/functionalities. These behaviors are activated when they are picked by the player. For simplicity let's assume each item will print different messages after being touched by the player.
In my previous SRP article, I demonstrated the player movement and collision detection mechanism. So I am skipping that part now.

In the above script, we are using an enum for differentiating the collectible items. When the player collided with an item OnCollided callback function is called. Inside that function, it checks the item type and prints a specific message for that collectible. It works fine for now.
But assume you have to implement a new collectible for extra_life.In this code structure for adding a new item, we have to add that item type item on the enum and also need to add an extra switch case for that item. So we have to modify our previous code and implement different logic for each item. This is a clear violation of OCP and SRP. Just imagine what will happen if we need to add hundreds of items and each item has different implementations. That will be a thousand line script and maintaining that script will be impossible. Let's solve this problem using OCP.

Refactoring Code using OCP:

First, create an interface ICollectable .

We created new scripts for each collectible type that contains the behavior and implement ICollectable interface. You have to attach these behavioral scripts with specific collectible objects in the Unity editor.

The above scripts are self-explanatory. We can write all our item specific logic on those individual scripts.OnCollectableCollided callback function will call automatically when the player touched an item. For functioning this process we have to refactor our previous CollectableController class.

Each collectible object already attached with specific collectible scripts (eg: Collectable_Sword, Collectable_Gun, etc). Now we have to attach the above script with all collectible objects.
The above script is simple. When an item collides with a player OnCollided callback function is called (For Collision detection mechanism see my SRP article). Inside that function, we call the OnCollectableCollided function from ICollectable interface. So if our collectible item is Sword then OnCollectableCollided function from Collectable_Sword script will call.

In this codebase, we can easily add a new feature without impacting the previous implementations. For example, adding a new collectible item (eg: Extra_life) we just need to create another behavioral script (eg: Collectable_ExtraLife). We do not need to modify the ColletableController_OpenClose script. So we closed the ColletableController for modification and open the individual collectible behavioral scripts for the extension.

I hope you get the idea about OCP. You can check the full project here. Feel free to knock me on Linkedin. I will write about the Liskov Substitution Principle(LSP) in my next article.

--

--