8장에서 살펴본 다양한 의존성 관리 기법들을 원칙이라는 관점에서 정리하자는 것이 9장의 주제다.
개방-폐쇄 원칙 OCP (Open-Closed Principle)
- 소프트웨어 개체(클래스, 모듈, 함수 등등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다.
- '확장'과 '수정'
- 확장 = 동작의 관점, 수정 = 코드의 관점
- '확장'에 대해 열려 있다 : 애플리케이션의 요구사항이 변경될 때 이 변경에 맞게 새로운 '동작'을 추가해서 애플리케이션의 기능을 '확장'할 수 있다.
- '수정'에 대해 닫혀 있다 : 기존의 '코드'를 수정하지 않고도 애플리케이션의 '동작'을 추가하거나 변경할 수 있다.
OCP는 유연한 설계란 기존의 코드를 수정하지 않고도 애플리케이션의 동작을 확장할 수 있는 설계라고 이야기한다. 애플리케이션의 동작을 확장하려면 일반적으로 어찌되었든 코드를 수정해야 하는데 어떻게 코드를 수정하지 않고도 동작을 추가할 수 있는 것일까?
사실 OCP는 런타임 의존성과 컴파일타임 의존성에 관한 이야기다(8장 참고).
- 런타임 의존성 : 실행시에 협력에 참여하는 객체들 사이의 관계
- 컴파일타임 의존성 : 코드에서 드러나는 클래스들 사이의 관계
- 8장에서 얘기했듯이 유연하고 재사용 가능한 설계에서 런타임 의존성과 컴파일타임 의존성은 서로 다른 구조를 가진다.
- OCP를 수용하는 코드는 컴파일타임 의존성을 수정하지 않고도 런타임 의존성을 쉽게 변경할 수 있는 코드이다.
예를들어 8장 마지막 부분에서 나왔던 Movie의 경우
- 확장에 대해 열려 있다 : 새로운 할인 정책을 추가해서 기능을 확장할 수 있도록 허용한다.
- 수정에 대해서는 닫혀 있다 : 기존 코드를 수정할 필요 없이 새로운 클래스를 추가하는 것만으로 새로운 할인 정책을 확장할 수 있다.
추상화가 핵심이다
- 추상화 : 핵심적인 부분만 남기고 불필요한 부분은 생략함으로써 복잡성을 극복하는 기법
- OCP의 핵심은 추상화에 의존하는 것이다.