개방-폐쇄 원칙 (OCP)
in Development on Design Pattern
개방-폐쇄 원칙(OCP)이란?
소프트웨어 엔티티 (클래스, 모듈, 함수 등)는 확장을 위해 열려 있어야하지만 수정을 위해 닫혀 있어야한다.
→ 기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다.
OCP 원칙을 어긴 예시
User
클래스가 Logic
클래스의 기능들을 사용한다고 가정하자. 만약 새로운 클래스인 newLogic
이 생겨서, User
클래스가 상황에 맞게 Logic
클래스를 사용하거나 newLogic
클래스를 사용할 수 있도록 구조를 짜야 된다고 가정하자. User
가 Logic
클래스를 직접적으로 사용하고 있기 때문에, User
가 newLogic
클래스를 사용할 수 있도록 구조를 바꾸려면 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를 지키지 않게 되면 특정 기능을 변경하거나 확장할 때, 그 기능을 사용하는 코드도 수정해야 되는 경우가 발생할 것이다. 즉, 이미 사용 중인 클래스 내부의 코드를 수정하게 되면, 사이드 이펙트(특정 코드를 수정했을 때 다른 기능들이 정상 작동하지 않는 경우)가 발생할 가능성이 높아진다. 또한 수정한 코드의 정상작동 뿐만 아니라 사이드 이펙트 발생 유무도 번거롭게 테스트해야 한다.