OCP – The Open-Closed Principle

The Open-Closed Principle

The Open-Closed principle is a part of SOLID, a mnemonic acronym that bundles a total of 5 design principles.

It is often associated with clean code.

But what exactly is it, is it important to you, and should you even care?

What does it state?

The statement it sets is pretty straightforward:

Software entities should be open for extension, but closed for modification“.

And entities can be a lot:

  • classes
  • modules
  • functions
  • etc.

To put it another way: Entities should allow their behavior to be changed without the need to modify their own source code.

An Example

Take a look at the example below to get an idea of a use case for the open-closed principle.

Please keep the following in mind: This is only a very basic example, and there are of course other examples that would also present what this one does well.

const allowedRoles = [“DevOps”, “SRE”];
export function isAllowedToDeployChanges(user) {
  return allowedRoles.includes(user.role);

The code itself looks okay, but what if you wanted to add or remove a role to/from the allowed ones?

❌ Yes, you’d have to modify your source code.

This is exactly what the open-closed principle tries to prevent.

What does it try to prevent?

OCP tries to prevent us from writing software that is inflexible.

❌ If you had to modify your source code every time you simply wanted to modify some behavior, you wouldn’t be able to abstract logic away into libraries.

❌ You would also be very inflexible with your unit tests. Because as you’d have to modify existing code, you’d also have to add new or modify existing tests each time you make a change.

As you can imagine, this is a pretty inflexible and time-consuming thing to do.

But by enabling your users (even yourself) and giving them the flexibility to extend your logic, you circumvent such scenarios.

✅ Your code becomes more flexible, and you can abstract it away.

✅ And your tests only need to assert the base logic, without any specifics.

Applying the principle

Let’s try to fix the example code above and make it conform to the open-closed principle.

If that piece of code should be open for extension, it has to allow users to modify the roles that are allowed to deploy.

const allowedRoles = [“DevOps”, “SRE”];
export function isAllowedToDeployChanges(user) {
  return allowedRoles.includes(user.role);
export function addAllowedRole(role) {
export function removeAllowedRole(role) {
  const index = allowedRoles.indexOf(role);
  if (index > -1) {
    allowedRoles.splice(index, 1);

As you see, two functions were added.

✅ One to add a new role to the existing ones.

✅ One to remove a role from the existing ones.

All three functions should now make up the API of your module (so better export them), which allows everyone to alter behavior easily.

Should you care?

If you ask me, yes, you should. Following the principle actually saves a lot of time in the long run.

Who likes going back to old code regularly, simply to add a new enumeration or string value, including a modification of existing tests?

And who likes using (library) functionality which is so inflexible that you have to open an issue on GitHub every time you need something a little different?

If you can answer with “Not me” for each of these questions, you know what to do.

Before You Leave

If you liked this article, visit me on Twitter, and it would mean the world to me if you also liked and shared the thread on Twitter.

Oliver Jumpertz


Feel free to contact me

Contact Me



Join the Newsletter

You will regularly be informed about new content, special offers, and interesting information about software development.

Your data might be transferred to servers located in the USA. By subscribing, you agree to the data transfer. You can revoke your approval at any time by unsubscribing. For more information, please visit the privacy policy.

    We won't send you spam. Unsubscribe at any time.