OCP(Open-Closed Principle, 개방-폐쇄 원칙)은 객체지향 설계의 핵심 원칙 중 하나로, SOLID 원칙의 두 번째 항목을 말한다.
핵심 개념은 다음 한 문장으로 요약된다:
“소프트웨어 개체는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다.”
확장에 열려 있다(Open for extension)
→ 새로운 기능이나 요구사항이 추가될 때, 기존 코드를 수정하지 않고 새로운 코드를 추가하여 시스템을 확장할 수 있어야 함.
수정에 닫혀 있다(Closed for modification)
→ 기존의 잘 동작하는 코드(검증된 코드)는 가능한 한 변경하지 않아야 함.
즉, OCP는
변경에 의한 버그 위험을 줄이고, 확장성을 높이기 위한 설계 원칙을 말한다.
| 구분 | 의미 |
|---|---|
| 원칙 | 확장에는 열려 있고, 수정에는 닫혀 있어야 한다 |
| 목표 | 유지보수성, 확장성 향상 |
| 수단 | 추상화(Interface), 다형성, 의존성 주입(DI), 디자인 패턴 |
| 실무 예시 | 전략 패턴, 플러그인 구조, 정책 클래스 분리 등 |
public class DiscountService {
public double calculateDiscount(String memberType, double price) {
if (memberType.equals("VIP")) {
return price * 0.2;
} else if (memberType.equals("GOLD")) {
return price * 0.1;
} else {
return 0;
}
}
}
새로운 멤버 등급이 생길 때마다 if-else문을 수정해야 함 → OCP 위반
public interface DiscountPolicy {
double discount(double price);
}
public class VipDiscountPolicy implements DiscountPolicy {
public double discount(double price) { return price * 0.2; }
}
public class GoldDiscountPolicy implements DiscountPolicy {
public double discount(double price) { return price * 0.1; }
}
public class DiscountService {
private final DiscountPolicy discountPolicy;
public DiscountService(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
public double calculateDiscount(double price) {
return discountPolicy.discount(price);
}
}
새로운 할인 정책이 생겨도 DiscountService 수정 없이 새로운 클래스만 추가하면 됨.
즉, 확장에는 열려 있고, 기존 코드 수정에는 닫혀 있음.
| 디자인 패턴 | 설명 |
|---|---|
| 전략(Strategy) 패턴 | 런타임에 알고리즘(전략)을 바꿀 수 있게 하여 OCP 준수 |
| 템플릿 메서드(Template Method) | 상속을 통해 세부 동작을 확장 |
| 데코레이터(Decorator) | 기존 클래스에 수정 없이 기능을 덧붙임 |
| 플러그인 구조 | 인터페이스 기반으로 새로운 모듈을 쉽게 추가 |
ApplicationContext가 Bean 등록 확장에는 열려 있고, 내부 로직 수정에는 닫혀 있음.@Component 클래스 추가나 @Bean 등록은 확장 행위지만, Spring Core를 수정할 필요는 없음.