**OCP(Open-Closed Principle)**는 1988년 Bertrand Meyer가 “Object-Oriented Software Construction"에서 처음 제안했다. 마틴은 이 원칙이 소프트웨어 아키텍처를 연구하는 근본적인 이유라고 말한다.
OCP의 정의
“소프트웨어 개체(클래스, 모듈, 함수 등)는 확장에 대해 열려 있어야 하고, 수정에 대해 닫혀 있어야 한다.” — Bertrand Meyer, 1988
두 가지 의미
- 확장에 열림 (Open for Extension): 새로운 기능을 추가할 수 있어야 한다
- 수정에 닫힘 (Closed for Modification): 기존 코드를 변경하지 않아야 한다
언뜻 보면 모순처럼 보인다. 새 기능을 추가하면서 기존 코드를 수정하지 않는다니?
어떻게 가능한가?
추상화의 힘
비밀은 **추상화(Abstraction)**에 있다. 인터페이스나 추상 클래스를 통해:
- 고정된 부분(인터페이스)은 닫혀 있음
- 변하는 부분(구현)은 열려 있음
| |
flowchart TB
subgraph Closed [닫힌 부분 - 수정 안 함]
I[ReportGenerator Interface]
end
subgraph Open [열린 부분 - 확장 가능]
PDF[PdfReportGenerator]
Excel[ExcelReportGenerator]
HTML[HtmlReportGenerator]
Future[미래의 Generator...]
end
PDF -->|구현| I
Excel -->|구현| I
HTML -->|구현| I
Future -.->|구현| I
재무 보고서 예제
마틴은 재무 보고서 시스템 예제를 사용한다.
요구사항
- 재무 데이터를 웹 페이지에 표시
- 나중에 PDF, 흑백 프린터, 컬러 프린터 출력 추가 예정
잘못된 설계
| |
OCP를 적용한 설계
flowchart TB
subgraph Core [핵심 비즈니스 로직]
FR[FinancialReporter]
FD[FinancialData]
FR --> FD
end
subgraph Boundary [경계]
RP[ReportPresenter Interface]
end
subgraph Outputs [출력 어댑터]
WP[WebPresenter]
PP[PdfPresenter]
BP[BlackWhitePrinter]
CP[ColorPrinter]
end
FR --> RP
WP -->|구현| RP
PP -->|구현| RP
BP -->|구현| RP
CP -->|구현| RP
| |
아키텍처 수준의 OCP
OCP는 클래스 수준을 넘어 아키텍처 수준에서 더 큰 의미를 가진다.
컴포넌트 계층화
flowchart TB
subgraph Level1 [가장 높은 수준 - 가장 보호됨]
BL[비즈니스 로직]
end
subgraph Level2 [중간 수준]
C[컨트롤러]
P[프레젠터]
end
subgraph Level3 [낮은 수준]
DB[(데이터베이스)]
UI[사용자 인터페이스]
end
C --> BL
P --> BL
DB --> BL
UI --> C
UI --> P
수준이 높을수록 변경으로부터 보호받는다.
방향 제어 (Directional Control)
의존성의 방향을 제어하여 보호한다:
- A가 B에 의존하면, B의 변경이 A에 영향
- 따라서 중요한 것이 덜 중요한 것에 의존하면 안 됨
- 의존성 역전으로 방향을 제어
정보 은닉 (Information Hiding)
불필요한 정보는 숨긴다:
Controller가Interactor의 내부를 알 필요 없음Presenter가Controller를 알 필요 없음- 이행적 의존성(Transitive Dependency) 제거
OCP가 아키텍처의 근본인 이유
마틴은 말한다:
“OCP는 시스템의 아키텍처를 떠받치는 원동력 중 하나다.”
좋은 아키텍처의 목표
- 기능 추가 시 기존 코드 변경 최소화
- 영향 범위 예측 가능
- 확장 비용 최소화
OCP를 따르면 이 목표를 달성할 수 있다.
Clean Architecture와 OCP
Clean Architecture의 동심원 구조는 OCP의 구현이다:
flowchart TB
subgraph CleanArch [Clean Architecture]
E[Entities - 가장 보호됨]
U[Use Cases]
I[Interface Adapters]
F[Frameworks - 가장 변경 가능]
end
F -->|의존| I
I -->|의존| U
U -->|의존| E
- 안쪽: 높은 수준의 정책, 변경으로부터 보호
- 바깥쪽: 세부사항, 변경 가능
- 의존성: 바깥에서 안으로만
OCP 적용 패턴
1. Strategy 패턴
런타임에 알고리즘을 교체:
| |
2. Template Method 패턴
알고리즘의 골격은 고정, 세부 단계는 확장:
| |
3. Plugin 아키텍처
핵심에 플러그인을 꽂는 구조:
flowchart TB
Core[핵심 시스템]
P1[Plugin A]
P2[Plugin B]
P3[Plugin C]
P1 --> Core
P2 --> Core
P3 --> Core
OCP의 한계
완벽한 OCP는 불가능
모든 변경에 대해 닫혀 있는 것은 불가능하다. 어떤 변경은 기존 코드 수정이 불가피하다.
전략적 폐쇄
가장 가능성 높은 변경에 대해 닫아야 한다:
- 과거에 자주 변경된 것
- 비즈니스에서 변경을 예고한 것
- 경험에 기반한 예측
첫 번째 탄환
마틴은 말한다:
“우리는 ‘첫 번째 탄환’을 맞는다. 그리고 그 후에 리팩토링한다.”
완벽한 예측은 불가능하다. 변경이 발생하면 그때 OCP를 적용하여 미래의 유사한 변경에 대비한다.
핵심 요약
| 항목 | 내용 |
|---|---|
| 정의 | 확장에 열리고, 수정에 닫힘 |
| 방법 | 추상화, 인터페이스, 다형성 |
| 아키텍처 연결 | 의존성 역전, 계층화 |
| 목표 | 변경 영향 최소화 |
| 패턴 | Strategy, Template Method, Plugin |
“OCP의 목표는 시스템을 확장하기 쉬운 동시에 변경으로 인해 시스템이 너무 많은 영향을 받지 않도록 하는 데 있다.” — Robert C. Martin
다음 장에서는
다음 장에서는 LSP: 리스코프 치환 원칙을 다룬다. 이 원칙은 Barbara Liskov가 1988년에 정의한 것으로, 하위 타입이 상위 타입을 올바르게 대체할 수 있어야 한다는 것을 말한다.
![Featured image of post [Clean Architecture] 16. OCP: 개방-폐쇄 원칙](/post/cleanarchitecture/16-ocp-open-closed-principle/wordcloud_hu_a3135a25f12b1155.png)
![[Clean Architecture] 14. SOLID 원칙 서론](/post/cleanarchitecture/14-solid-principles-introduction/wordcloud_hu_b40e2016719b5d89.png)
![[Clean Architecture] 15. SRP: 단일 책임 원칙](/post/cleanarchitecture/15-srp-single-responsibility-principle/wordcloud_hu_8a6fa0e5a13a91ff.png)
![[Clean Architecture] 16. OCP: 개방-폐쇄 원칙](/post/cleanarchitecture/16-ocp-open-closed-principle/wordcloud_hu_a84054017b47f51d.png)
![[Clean Architecture] 17. LSP: 리스코프 치환 원칙](/post/cleanarchitecture/17-lsp-liskov-substitution-principle/wordcloud_hu_494cd6bbbdcbeefe.png)
![[Clean Architecture] 18. ISP: 인터페이스 분리 원칙](/post/cleanarchitecture/18-isp-interface-segregation-principle/wordcloud_hu_e792044eccd81103.png)
![[Clean Architecture] 12. 객체 지향 프로그래밍](/post/cleanarchitecture/12-object-oriented-programming-polymorphism/wordcloud_hu_6c2b4620fe50d548.png)
![[Clean Architecture] 19. DIP: 의존성 역전 원칙](/post/cleanarchitecture/19-dip-dependency-inversion-principle/wordcloud_hu_b2315221135160e2.png)