What is the open-closed principle?

The open-closed principle is the second principle of the SOLID design principles, namely:

SOLID Design Principles

The open-closed principle states that “the software entities should be open for extension but closed for modification”.

The idea of the principle is to design the code in a way such that new entities or functionalities can be added without modifying the existing code.

Why do we need it?

Consider a simple example of finding the index of a value in an array. The code will be as follows:

#include <iostream>
using namespace std;
int find(int key, int arr[], int arrsize){
for(int i=0; i<arrsize; i++){
if(arr[i] == key){
return i;
}
}
return -1;
}
int main() {
int arr[4] = {1, 2, 5, 7};
int key = 5;
cout<<key<<" found at index: "<<find(key, arr, 4);
return 0;
}

Explanation

The find function returns the index of key in the array arr of having arrsize number of elements. If key is not present in arr, it returns -1.

Now consider that we also want to find a word in an array of words. We will have to modify the above code as follows:

#include <cstring>
#include <iostream>
using namespace std;
int find(int key, int arr[], int arrsize){
for(int i=0; i<arrsize; i++){
if(arr[i] == key){
return i;
}
}
return -1;
}
int find(const char* key, const char* arr[], int arrsize){
for(int i=0; i<arrsize; i++){
if(strcmp(arr[i], key) == 0){
return i;
}
}
return -1;
}
int main() {
int arr[4] = {1, 2, 5, 7};
int key = 5;
cout<<key<<" found at index: "<<find(key, arr, 4)<<endl;
const char* arr2[] = {"abc", "edf", "fwet", "zc"};
const char* key2="edf";
cout<<key2<<" found at index: "<<find(key2, arr2, 4);
return 0;
}

Notice that the only difference between the functions is in the data types of input parameters of the find function and in if statements in lines 7 and 16, where the key and an array index are compared to see if they are equal.

If we want to define the find function of another data type, the input parameters and the comparison of the find function will be modified and we will write another find function. This violates the open-closed principle, because a new function is written for each data type, which means the code is not open for extension.

Solution

The open-closed principle proposes a solution to the aforementioned problem.

We can write a single find function that can be extended to as many data types as required without any modification in already written code.

#include <cstring>
#include <iostream>
using namespace std;
bool cmp(int k1, int k2){
if(k1==k2){
return true;
}else{
return false;
}
}
bool cmp(const char* k1, const char* k2){
if(strcmp(k1, k2) == 0){
return true;
}else{
return false;
}
}
template <typename T>
int find(const T key, const T arr[], int arrsize){
for(int i=0; i<arrsize; i++){
if(cmp(arr[i],key)){
return i;
}
}
return -1;
}
int main() {
int arr[4] = {1, 2, 5, 7};
int key = 5;
cout<<key<<" found at index: "<<find<int>(key, arr, 4)<<endl;
const char* arr2[] = {"abc", "edf", "fwet", "zc"};
const char* key2="edf";
cout<<key2<<" found at index: "<<find<const char*>(key2, arr2, 4);
return 0;
}

Explanation

The above find function is a template-based solution. Each data type implements its own cmp function that compares if two values are equal. To implement the find function of another data type, no modification is required. We only need to write the cmp function of that data type. Thus, the code above follows the open-closed principle.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved