개방-폐쇄 원칙 (OCP)

개방-폐쇄 원칙(OCP)이란?

소프트웨어 엔티티 (클래스, 모듈, 함수 등)는 확장을 위해 열려 있어야하지만 수정을 위해 닫혀 있어야한다.

→ 기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다.

OCP 원칙을 어긴 예시

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5c7a7147-4e6d-4796-90c6-651ad8184237/Untitled.png

User 클래스가 Logic 클래스의 기능들을 사용한다고 가정하자. 만약 새로운 클래스인 newLogic이 생겨서, User 클래스가 상황에 맞게 Logic 클래스를 사용하거나 newLogic 클래스를 사용할 수 있도록 구조를 짜야 된다고 가정하자. UserLogic 클래스를 직접적으로 사용하고 있기 때문에, UsernewLogic 클래스를 사용할 수 있도록 구조를 바꾸려면 User 클래스의 코드를 고쳐야만 한다.

정리하자면, Logic에 대한 기능을 확장하려 했는데, Logic에 대한 기능을 사용하는 User의 코드도 같이 수정해야 하는 것이다. 즉, OCP의 원칙을 어긴 것이다.

User 클래스가 Logic 클래스의 기능을 사용하는 예시

public class User {
    public void activate() {
        Logic logic = new Logic();
        logic.activate();
    }
}

public class Logic {
    public void activate() {...}
}

OCP 원칙을 어긴 코드 - Logic 클래스 뿐만 아니라, newLogic 클래스도 사용할 수 있도록 변경하기

public class User {
    public void activate(**String logic**) {
        if (logic.equals("logic")) {
            Logic logic = new Logic();
            logic.activate();
        } else if (logic.equals("newLogic")) {
            newLogic logic = new newLogic();
        }
    }
}

public class Logic {
    public void activate() {...}
}

public class newLogic {
    public void activate() {...}
}

newLogic이라는 기능을 추가적으로 확장할 때, Logic, newLogic이라는 기능을 사용하는 User의 클래스가 코드를 조금이라도 추가를 해야만 기능 확장이 가능하므로 OCP 원칙을 어긴 것이다.

OCP 원칙을 지킨 형태로 코드를 다시 짜게 되면…?

User 클래스가 Logic 클래스의 기능을 사용하는 예시

public class User {
    public void activate(Logic inputLogic) {
        Logic logic = inputLogic;
        logic.activate();
    }
}

public class Logic {
    protected void activate() {...}
}

public class ALogic {
    @Override
    public void actiavte() {...}
}

⭕️ OCP 원칙을 어긴 코드 - Logic 클래스 뿐만 아니라, newLogic 클래스도 사용할 수 있도록 변경하기

public class User {
    public void activate(Logic inputLogic) {
        Logic logic = new Logic();
        logic.activate();
    }
}

public class Logic {
    protected void activate() {...}
}

public class ALogic {
    @Override
    public void activate() {...}
}

public class BLogic {
    @Override
    public void activate() {...}
}

newLogic이라는 기능을 추가적으로 확장할 때, Logic, newLogic이라는 기능을 사용하는 User의 클래스가 코드를 조금이라도 변경되지 않았으므로 OCP 원칙을 잘 지킨 것이다.

OCP를 지키지 않았을 때의 문제점

OCP를 지키지 않게 되면 특정 기능을 변경하거나 확장할 때, 그 기능을 사용하는 코드도 수정해야 되는 경우가 발생할 것이다. 즉, 이미 사용 중인 클래스 내부의 코드를 수정하게 되면, 사이드 이펙트(특정 코드를 수정했을 때 다른 기능들이 정상 작동하지 않는 경우)가 발생할 가능성이 높아진다. 또한 수정한 코드의 정상작동 뿐만 아니라 사이드 이펙트 발생 유무도 번거롭게 테스트해야 한다.

References