OCP: 개방-폐쇄 원칙

  • 개방-폐쇄 원칙이라는 용어는 1988년 버트란트 마이어(Bertrand Meyer)가 만듬
    • 소프트웨어 개체(artifact)는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야함
    • 즉 개체의 행위는 확장할 수 있어야 하지만, 이때 개체를 변경해서는 안됨
  • 소프트웨어 아키텍처를 공부하는 가장 근본적인 이유가 이것
    • 만약 요구사항을 살짝 확장하는데 엄청난 수정이 필요하다면 설계의 실패에 맞닥뜨린것임
  • 클래스와 모듈 뿐만아니라 아키텍처 컴포넌트 수준에서 더 중요한 의미를 가짐

사고 실험

  • 지금부터 재무제표를 웹으로 보여주는 시스템이 있다고 생각해봄
    • 웹 페이지에 표시되는 데이터는 스크롤 할 수 있음
    • 음수는 빨간색으로 출력
    • 이해관계자가 동일한 정보를 보고서 형태로 변환해서 흑백 프린터로 출력을 요청
      • 페이지 번호, 머리글, 바닥글, 표의 각 열에는 레이블, 음수는 괄호처리
    • 원래 코드에서 얼마나 많이 수정해야할까?
  • 아키텍처가 훌륭하다면 변경되는 코드량이 최소화 되어야함
  • 어떻게 해야할까?
    • 서로 다른 목적으로 변경되는 요소를 적절하게 분리(단일 책임 원칙, SRP)
    • 이들 요소 사이의 의존성을 체계화함(의존성 역전 원칙, DIP)
  • 단일 책임 원칙을 적용하면 아래와 같이 구성가능

  • 보고서 생성이 두개의 책임으로 분리
    • 변경이 필요한 부분만 수정 가능
  • 이러한 목적을 달성하려면 아래와 같이 처리 과정을 클래스 단위로 분리
    • <I>는 인터페이스, <DS>는 데이터 구조
    • 화살표가 열려있다면 사용, 닫혀있다면 구현 또는 상속

  • 주목할 점은 의존성(화살표)은 소스 코드의 의존성을 나타냄
    • 이중선 단위의 화살표는 한 방향으로만 존재
    • *Presenter에 변경이 발생해도 Controller는 수정이 필요없음
    • 어떠한 변경도 Interactor에 영향을 주지않음
      • Interactor는 업무 규칙을 포함
      • 애플리케이션에서 가장 높은 수준의 정책을 포함
      • 보호 계층구조가 수준이라는 개념을 바탕으로 구성됨
    • 이것이 아키텍처 수준에서 OCP가 동작하는 방식
      • 저수준 컴포넌트에서 발생한 변경으로부터 고수준 컴포넌트를 보호할 수 있음

방향성 제어

  • FinancialDataGatewayFinancialReportGeneratorFinancialDataMapper사이에 존재하는 인터페이스
    • 의존성 역전을 위해 존재

정보 은닉

  • FinancialReportRequest는 방향성 제어와는 다른 목적을 위해 사용
    • FinancialReportControllerInteractor내부에 대해 너무 많이 알지 못하도록 막기 위해 존재

결론

  • OCP의 목표는 시스템을 확장하기 쉬운 동시에 변경으로 인해 시스템이 너무 많은 영향을 받지 않도록 하는데 있음
  • 이러한 목표를 위해 컴포넌트 단위로 분리, 저수준 컴포넌트에서 발생한 변경으로 부터 고주순 컴포넌트를 보호할수 있는 계층 구조로 구성