정의
소프트웨어 개체의 행위는 확장할 수 있어야 하지만, 이때 개체를 변경해서는 안 된다.
만약 새로운 요구사항을 반영하기 위해 기존 코드를 광범위하게 수정해야 한다면, 그 구조는 OCP를 위반하고 있는 것이다.
단일 책임 원칙과 OCP
기능을 잘게 나누고 각각의 책임을 분리하는 단일 책임 원칙(SRP)은 OCP를 실현하기 위한 선행 조건과 같다.
SRP가 잘 지켜진 구조에서는 새로운 기능을 추가하더라도 기존 코드의 수정은 최소화된다.
책임의 분리가 확장의 단위를 만들어 주기 때문이다.
예시: 도서 추천 시스템
한 온라인 서점에서 사용자가 책을 검색하면, 기본적으로 텍스트 기반 정보(제목, 저자, 요약)가 출력된다.
마케팅팀이 갑자기 말한다.
"추천 도서 섹션에서는 이미지와 키워드를 중심으로 더 시각적으로 보여주고 싶어요."
이제 시스템은 두 가지 출력 방식을 제공해야 한다:
- 일반 검색 결과 → 텍스트 기반 정보
- 추천 도서 섹션 → 이미지 기반 시각 정보
이때 기존 출력 로직을 조건문으로 복잡하게 만들기보다는, 출력 책임을 분리해서 각각 독립적으로 구성하는 것이 바람직하다.
책임 분리 구조
- 책 데이터를 수집/구성하는 책임
- 출력 형식(텍스트 / 시각화)에 따른 변환 책임
- 일반 검색 결과 → 텍스트 기반 정보
- 추천 도서 섹션 → 이미지 기반 시각 정보
책임을 분리하면, 새로운 View를 추가하더라도 기존 기능(일반 검색 결과)를 손대지 않는다.
바로 이 점이 개방-폐쇄 원칙이 말하는 '변경 없이 확장'이다.
아키텍처 관점에서 OCP 지키기
아키텍처 관점에서 OCP를 지키기 위해 중요한 원칙 중 하나는 컴포넌트 간의 의존성 방향 제어다.
이를 위해 도서 추천 시스템은 다음과 같은 계층 구조로 나눌 수 있다:
- BookController: 사용자 요청을 받아 처리 흐름을 제어
- BookInteractor: 핵심 비즈니스 로직
- BookPresenter: 화면 출력 방식에 맞게 데이터를 변환 (텍스트/시각화)
- BookView: 실제 UI 구성 요소 (예: HTML, PDF)
- BookDatabase: 영속 데이터 저장소
도서 추천 시스템 내 의존 구조는 다음과 같이 계층적으로 정리할 수 있다:
[BookView] [BookView]
↓ ↓
[View Interface] [BookPresenter]
↑ ↓
[BookPresenter] [BookController]
↓ ↓
[Presenter Interface] [BookInteractor]
↑ ↑
[BookController] [BookDatabase]
↓
[Controller Interface]
↑
[BookInteractor]
↓
[Database Interface]
↑
[BookDatabase]
- 화살표 방향은 의존성이 향하는 방향을 의미한다.
- 의존 당하는 상위 계층은 의존하는 하위 구현체를 모른다.
View, Presenter에 발생한 변경이 Controller나 Interactor에 영향을 주면 안 된다.
Interactor는 다른 객체의 변경에 영향받지 않도록 중앙에 위치해야 한다.
이 계층적 보호 구조 덕분에, 새로운 출력 방식(PDF, 모바일 앱 등)을 추가하더라도
Interactor나 Controller는 아무런 영향을 받지 않으며, 새로운 View와 Presenter만 작성하면 된다.
이는 개방-폐쇄 원칙의 이상적인 예다.
인터페이스의 역할
인터페이스는 단순한 추상화 수단이 아니다.
- 의존성 역전(DIP): 하위 구현체가 상위 모듈에 영향을 주지 않도록 경로를 뒤집는다.
- 추이 종속성 차단: 직접 사용하지 않는 모듈에 간접적으로 의존하지 않게 한다.
예:
A → B → C // 추이 종속성
이 상황에서 A는 C에 영향을 받을 수 있다.
이를 막기 위해선:
A → I ← B → C // 인터페이스 I로 의존성 단절
이처럼 인터페이스는 변경 전파를 차단하는 방패 역할을 한다.
결론
OCP는 시스템을 "유연하게 확장"하면서도 "기존 코드는 보호"하는 것을 목표로 한다.
이를 위해선
- 단일 책임 원칙으로 책임을 나누고
- 인터페이스로 의존성을 역전시키며
- 변경 방향이 위로 흐르지 않도록 계층을 설계해야 한다.
※ 본 글은 『Clean Architecture』(로버트 C. 마틴 저) 3부의 8장을 기반으로 학습 목적으로 요약한 글입니다.
※ 이 글은 책의 내용을 요약한 것으로, 원문 없이 읽을 경우 오해의 여지가 있을 수 있습니다. 정확한 이해를 위해 원서의 정독을 권장합니다.
'개발 관련 지식' 카테고리의 다른 글
Clean Architecture 정리 - 3부 10장 인터페이스 분리 법칙 (0) | 2025.06.14 |
---|---|
Clean Architecture 정리 - 3부 9장 리스코프 치환 원칙 (0) | 2025.06.13 |
Clean Architecture 정리 - 3부 7장 단일 책임 원칙 (0) | 2025.06.10 |
Clean Architecture 정리 - 2부 6장 함수형 프로그래밍 (1) | 2025.06.09 |
Clean Architecture 정리 - 2부 5장 객체지향 프로그래밍 (1) | 2025.06.08 |