SOLID — Open Closed Principle Practise

Foreword

Zong Yuan
2 min readSep 21, 2023

Few days ago a colleague showed me a blind spot in a rapid growing class that the class is not following open closed principle. So I am going to write it down for future reminder.

Original simplified sample code

public class LogicExecutorService {
private final static String TYPE_A = "A";
private final static String TYPE_B = "B";
private final static String TYPE_C = "C";

public void executeForA() {
execute(TYPE_A);
doSomethingExtraA();
}

public void executeForB() {
execute(TYPE_B);
doSomethingExtraB();
}

public void executeForC() {
execute(TYPE_C);
doSomethingExtraC();
}

private void execute(String type) {
// ... execution here
}
}

As you can see from sample above, whenever developers have to add a new type to the LogicExecutorService, we have to modify this class. In other words, it is already against the open closed principle.

Refactor Idea

In order to close the LogicExecutorService but still open for future new type extension, my refactor idea is using an interface in the LogicExecutorService to get the type as well as execute the doSomethingExtra.

public interface LogicExecutor {
String getType();
void doSomethingExtra();
}

So the modified LogicExecutorService

public class LogicExecutorService {
public void execute(LogicExecutor executor) {
execute(executor.getType());
executor.doSomethingExtra();
}

private void execute(String type) {
// original execute
}
}

And we can create different classes for the implementations.

public class LogicA implements LogicExecutor {
@Override
public String getType() {
return "A";
}

@Override
public void doSomethingExtra() {
// do something extra for A
}
}

// Similar for B and C

And the usage will be something like this

LogicExecutorService logicExecutorService;
// init logicExecutorService
logicExecutorService.execute(new LogicA());

And now we can add more type D and type E without modifying LogicExecutorService.

--

--