[What does the letter “O” in S.O.L.I.D stand for?] — The Duty of the Developer As A Professional #7

Linh NGUYEN
6 min readOct 19, 2020

--

Hi Re-Programmerz!

In the continuity of our series The Duty of The Developer as a Professional and as promised in our previous article The Golden Rule to choose a good Architecture, we will see in details the five SOLID principles, this time with the second letter: O for Open-Closed Principle (OCP).

Definition

This programming principle is first introduced by Bertrand Meyer in 1988, states that:

“Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.”

It is later reformulated by Robert C. Martin as follows:

“You should be able to extend the behavior of a system without having to modify that system.”

Different approaches

What OCP is about, is that it should not be a huge effort to change the behavior of a module (open for extension), and this change should not cause any source code change (closed for modification). A module, once compiled, should not be modified and be recompiled. Instead, it should be leaved as-is, and be extended when there is a need for behavior changes.

To achieve this goal, Bertrand Meyer proposed using Inheritance

“A class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its clients.”

Robert C. Martin, in his talks and books, suggests using Polymorphism (abstract classes or interfaces) while conforming to two other principles: Single Responsability Principle and Dependency Inversion Principle.

How do I know if OCP is not respected in my code?

Now, let us understand, at first, with a theoretical example, then we will bring some code in action!

In a role-playing PC game, movements and actions are triggered by the keyboard.

  • To attract more players, the game company wants these to be handled also by different kinds of inputs (gamepads, joysticks…). Having OCP in mind while developing the game (and other SOLID principles as well), each time there is a new input source coming to life, the development team simply add an implementation for this new one and add this to the input options list.
  • Later, for whatever the reason is, the game company decides that the Y gamepad will no longer be supported. This should require little effort from the team: delete Y gamepad’s implementation, remove Y gamepad from the input options list, the job is done. The flexibility of code makes removal as “easy” as addition.

In both cases, all other main game modules should stay unchanged, which save the team from recompiling millions of lines of source code.

… let us do some code !

The above code snippet contains an InputController class implementing a pause function that took one parameter : input typed as a GameControlInput.

The implementation of the pause function is some switch statement on the type of the input parameter in order to call the correct code of thepause action on the correct input controller.

In other words:

  • If the input parameter is a Keyboard, the Keyboard.selectEsc is called.
  • If the input parameter is an XboxGamePad, the XboxGamePad.selectMenu is called.
  • If the input parameter is a PlayStationGamePad, the PlayStationGamePad.selectOption is called.

It’s not perfect, but it does the job, let us continue…

A new requirement appears…!

The Y game pad appears on the market and the company wants to stay up-to-date by supporting this new one in their game.

What happens above?

We create a new class named YGamePad with the same type as the other inputs.

Now we have to modify the pause function in order to use this new class…

Wait…What?!

Clearly here, we are violating the OCP. Our InputController class should be open to extension, not to modification!

How can we do that though? OCP in action !

Let us do some little changes…

  • The GameControlInput is no longer a class, but an Interface.
  • The pause function inside the InputController class has a parameter whose type conforms toGameControlInput Interface.
  • The pause function implementation is done by a single call of the only method known by the inputparameter : pause .
  • The Keyboard, XboxGamePadand PlayStationGamePad classes, now conform to GameControlInput, have to provide their own and correct implementations of the pause method ! The InputController has nothing to do with that.

Now that the OCP is respected, let us manage the new requirement!

We no longer need to modify the pause function!

What we should do is simple: create a YGamePad class that conforms to the GameControlInput Interface and implement the pause function there!

When OCP is respected and an extension is planned on your system, you only have to add new code to fulfill the task while the old one remains untouched. A code that is written once, well designed, and does not have to change could hardly become a bad code through time.

Moreover, in a customer’s point of view, when he asks to add a new feature, he actually thinks that we are adding, not modifying the old ones!

Conclusion

OCP is awesome, but is not ultimate.

The OCP-compliance design does not aim to make a system immune to all kinds of changes but only those related to the behavior extension of a class. Applying OCP while designing the code helps reduce the impacts and minimize the development team’s effort but large-scaled modifications are sometimes inevitable. This is why other design principles exist to help us enhance our code furthermore.

“The Open-closed principle is the moral center of system architecture. And while moral perfection may not ever be attainable, it’s certainly worth striving for.”

— Robert C. Martin, aka Uncle Bob

It is our job as developer to know, understand and apply the other S.O.L.I.D principles in our code to improve its quality.

Next article: the third letter from S.O.L.I.DL for Liskov Substitution Principle!

We hope that you acquired something useful today with this post! Give us claps if you liked it and do not hesitate to share it as much as you can! 🔥

This article is co-written with Abderrahim Benmakhlouf

--

--