로버트 마틴이 생각하는 OCP

Kim Dong Kyun·2024년 4월 4일
0
post-thumbnail

OCP

"소프트웨어 개체(artifact)는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다"

다시말해, 개체의 행위는 확장 할 수 있어야 하는데, 이 확장에 의한 변경은 최소화해야 한다.

  • 이미 돌아가는 모듈에 새로운 행위를 추가하거나, 행위를 변경했을 때 이 추가나 변경이 소프트웨어 대부분에 많은 변화를 요구해서는 안된다.

OCP의 재료

  1. SRP 를 잘 준수한 모듈
  • 다른 목적으로 변경되는 요소를 적절하게 분리한다.

"하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다."
[이전 글]

  1. 의존성을 체계화 한다

책임을 분리하는 것, 요소를 분리하는 것은 필연적으로 더 많은 요소가 등장하게 한다. 그리고 이 요소간의 적절한 행위 교환이 소프트웨어를(객체지향 소프트웨어를) 더 유연하게 만든다.

이렇게 요소간의 상호작용은 필연적으로 한 쪽으로의 의존성을 만들게 되는데, 이 의존성을 어디로 향하게 할 것인가가 바로 IoC 의 핵심이며, OCP를 지키기 위한 가장 필수적인 조건이다.


의존성 역전 예시

의존성 역전의 컨셉트는 이렇다.

  1. 상위 모듈에서 호출하지만(즉 제어하지만), 하위 모듈에서 결정한다.

"제어 흐름과 소스코드 의존성이 다르다"

김영한님의 스프링 강의를 들어보면 할인 정책에 대한 이야기가 나온다.

주문 객체 -> 할인 정책 인터페이스의 discount()

할인 정책 인터페이스 -> {퍼센트 할인 percentDiscount(), 가격 할인 amountDiscount()}

제어하는 측, 즉 호출하는 측은 인터페이스 매서드인 discount() 를 호출하지만, 런타임에는 하위 모듈이 이 일을 실행한다 (즉 하위 모듈의 구현에 의존한다)

이 컨셉트는 다형성 에 대한 예시이기도 하다.


잘 분리된 의존성이란?

덜 중요한 일로부터 더 중요한 일을 보호하는 것이 의존성을 분리하는 기준이며,

더 중요한 일이 잘 지켜지는 형태가 의존성이 잘 분리되었다고 말할 수 있따.

예를 들어, 회계 통계(report)를 작성하는 프로그램을 작성한다고 생각하자.

위와 같이 Appreance, Interactor(통계 데이터를 계산(생성)하는 중요한 로직을 가진다), Database 컴포넌트로 분리하여 컴포넌트를 설계했다.

위 형식에서 내가 캐치한 특성은

  1. 컴포넌트 간의 인터랙션은 인터페이스를 통해 이루어진다.
  • 컴포넌트 간의 데이터, 혹은 객체의 이동이 의존성 높아질 수 있는 가장 결정적인 순간이라고 판단된다.

책에서 예를 들었던 대로, Mapper 를 통해 Finance 엔티티의 정보를 맵핑하고 그 정보를 GateWay 라는 인터페이스를 거쳐서 Generator에서 사용하고 있는 것은 프로그램에서 가장 중요한 로직(업무 규칙)을 포함하는 Interactor 컴포넌트에서 Database 컴포넌트를 직접적으로 알지 못하게 하려는 의도이다.

  1. 모든 컴포넌트 관계는 단방향으로 이루어진다.

중요도 순서로 나열 해 보자.

View(웹 등) -> Presenter(위에서는 생략) -> Controller || Database -> Interactor

이 순서대로 보았을 때 Interactor 는 OCP를 가장 잘 지킬 수 있는 곳에 위치한다.

즉 인터랙터를 제외한 다른 모든 컴포넌트에서 발생한 어떤 변경도 Interactor에 영향을 주지 않는다.

즉 가장 중요한 컴포넌트에 가장 높은 순위의 자유도를 부여하고(OCP를 준수하고) 관리해야 한다.

  1. "추이종속성" 이란 클래스 A가 B에 의존, B가 C에 의존하여 결국은 A->B->C 형태의 의존을 가지게 되는 것을 말한다.

위 다이어그램에서 ReportGenerator -> ReportRequester(Interface) -> Controller 로 향하는 의존을 설계한 이유도 추이종속성을 제거하기 위함인데, Controller 가 Interactor 의 세부 구현에 대해서 너무 많이 알게 되면 자연스럽게 Finance 엔티티에 대해 추이 종속성을 가지기 때문이다.


나의 생각

결론적으로 OCP의 준수는 SRP의 엄격한 준수, 캡슐화, 그리고 어떤 컴포넌트가 가장 중요한지 판단해서 컴포넌트간의 흐름을 적절한 다형성으로 제어하는 것으로 이루어진다고 생각된다.

2개의 댓글

comment-user-thumbnail
2024년 4월 7일

멋있습니다.

1개의 답글