컴포넌트 결합

Gooreum·2021년 11월 5일
0

클린아키텍처

목록 보기
14/33
  • 컴포넌트 사이의 의존성을 어떤 기준으로 만들 것인가를 살펴본다.

ADP:의존성 비순환 원칙

💡 컴포넌트 의존성 (그래프)에 순환이 있어서는 안 된다.

ADP는 어떻게 하면 효율적인 통합을 할 수 있는가에 대한 해결책이다.

  • 릴리스 버전 단위의 컴포넌트 별로 분리하여 개발한다. → 다른 팀(컴포넌트)로부터의 영향이 작아진다.
  • 컴포넌트 사이의 의존성 구조를 반드시 관리해야한다.
    • 이때 의존성 구조에 순환이 있어서는 안 된다.
  • 컴포넌트 구성요소간 의존성을 파악하고 있으면 시스템을 빌드하는 방법을 알 수 있다.

좀 더 자세히 이해하기 위해 아래 컴포넌트 다이어그램을 살펴보자.

이미지 출처 : https://icarus8050.tistory.com/47?category=402908

  • Main, View, Controllers, Presenters, Interactors, Authorizer, Database, Entities 컴포넌트로 분리되어 있다.
  • 이 다이어그램은 의존성 구조가 비순환 방향을 나타낸다. 어떤 컴포넌트에서 출발하여도 자기 자신으로 되돌아가지 않는다.
  • Presenters 컴포넌트의 새로운 릴리스를 만들면 Main과 View 두 컴포넌트를 책임지는 팀과의 커뮤니케이션만 진행하면 된다
  • Main은 새로 릴리스 되더라도 시스템에서 이로 인해 영향받는 컴포넌트가 전혀 없다.
  • 테스트 구성 노력이 적어진다.
    • Presenters 컴포넌트 테스트를 위해선 Interactors, Entities를 이용해서 Presenters 자체 버전을 빌드하면 그만이다.
  • 시스템 전체를 릴리스 해야 할 때가 오면 릴리스 절차는 상향식으로 진행된다. → 빌드 방법 알려줌. (1) Entities → (2) Database, Interactors → (3) Presenters, View, Controllers, Authorizer → (4) Main

만약 순환이 생길 수 밖에 없는 상황이 발생하면 어떻게 될까 → 무조건 없애야 한다..

이미지 출처 : https://icarus8050.tistory.com/47?category=402908

Entities가 Authorizer 컴포넌트의 Permissions 클래스를 사용해야 하는 상황을 가정해보자.

  • Entities 컴포넌트가 Authorizer에 의존성이 생겨 컴포넌트 의존성 구조에 순환이 생긴다.

    • 컴포넌트 분리 실패
    • 모든 팀이 각자의 컴포넌트를 수정 배포하려고 해도 복잡성이 높아짐.
    • 테스트가 어려워짐.
    • 올바른 빌드 방식을 파악하기 어려워짐.
  • 그럼 이처럼 순환이 생겼을 때 어떻게 해결할 수 있을까?

    (1) 의존성 역전 원칙(DIP)을 적용한다.

    이미지 출처 : https://icarus8050.tistory.com/47?category=402908

    • User가 필요로 하는 메서드를 제공하는 인터페이스를 생성한다.

    • 인터페이스는 Entities에 생성하고, Authorizer에서는 이 인터페이스를 상속받는다.

      (2) Entities와 Authorizer가 모두 의존하는 새로운 컴포넌트를 만든다.

      그리고 두 컴포넌트가 모두 의존하는 클래스들을 새로운 컴포넌트로 이동시킨다.

      이미지 출처 : https://icarus8050.tistory.com/47?category=402908

    • 이 방식이 의미하는 바는 요구사항이 변경되면 컴포넌트 구조도 변경될 수 있다는 사실이다.

    • 실제로 애플리케이션이 성장함에 따라 컴포넌트 의존성 구조는 흐트러지며 성정한다.

    • 따라서 의존성 구조에 순환이 발생하는지를 항상 관찰해야 한다.

하향식(top-down) 설계

  • 컴포넌트 의존성 다이어그램은 일종의 지도이다. (지도는 그곳을 가봐야 그릴 수 있는 것, 가보지도 않은 곳을 지도에 담을 순 없다.)
  • 애플리케이션이 성장함에 따라 재사용 가능한 요소를 만드는 일에 관심을 기울기 시작하게 되고, CRP가 영향을 미치기 시작한다. 그러다 순환이 발생하면 ADP가 적용되고, 컴포넌트 의존성 그래프는 조금씩 흐트러지고 또 성장한다.
  • 그러나 그 지도는 자주 변경되는 컴포넌트로부터 안정적이며 가치가 높은 컴포넌트를 보호하고자 하는 방향으로 그려진다. 이를 통해 의존성 구조는 변동성을 격리하는 방향으로 나아간다.
  • 이러한 이유로 컴포넌트 구조는 프로젝트 초기에 설계할 수 없고 하향식으로 설계될 수 없다.

SDP: 안정된 의존성 원칙

💡 안정성의 방향으로(더 안정된 쪽에) 의존하라.
  • 설계시 공통 폐쇄 원칙(CCP)을 준수함으로써 컴포넌트가 다른 유형의 변경에는 영향받지 않으면서도 특정 유형의 변경에만 민감하게 만들 수 있다.
  • 컴포넌트는 항상 변경될 수 밖에 없지만 변동성이 큰 컴포넌트, 덜 큰 컴포넌트로 구분하여 설계할 수 있다. 이때 변동성이 적은 컴포넌트가 변동성이 큰 컴포넌트를 의존하게 해서는 안 된다.
  • 안정된 의존성 원칙(SDP)을 준수하면 변경하기 어려운 모듈이 변경하기 쉽게 만들어진 모듈에 의존하지 않도록 만들 수 있다.

어떤 컴포넌트가 안정성있는 컴포넌트인가.

  • 수많은 다른 컴포넌트가 해당 컴포넌트 안쪽으로 들어오는 의존성이 많아지면 상당히 안정적이라고 볼 수 있다. 사소한 변경이라도 의존하는 모든 컴포넌트를 만족시키면서 변경하려면 상당한 노력이 들기 때문이다. ex) Java String 클래스

안정성 지표

  • 컴포넌트 안정성을 측정해주는 지표/공식
  • 컴포넌트로 들어오고 나가는 의존성의 개수를 세어 보는 방법이다.
  • Fan-in : 안으로 들어오는 의존성. 컴포넌트 내부의 클래스에 의존하는 컴포넌트 외부의 클래스 개수를 나타낸다.
  • Fan-out : 밖으로 나가는 의존성. 컴포넌트 외부의 클래스에 의존하는 컴포넌트 내부의 클래스 개수를 나타낸다.
  • I(불안정성) : I = Fan-out / (Fan-in + Fan-out). [0,1] 범위의 값을 갖는다. I = 0이면 최고로 안정된 컴포넌트라는 의미. I = 1 이면 최고로 불안정한 컴포넌트라는 의미.
  • SDP에서 컴포넌트의 I 지표는 그 컴포넌트가 의존하는 다른 컴포넌트들의 I보다 커야 한다고 말한다. 즉, 의존성 방향으로 갈수록 I 지표 값이 감소 해야 한다.

모든 컴포넌트가 안정적이어야 하는 것은 아니다.

  • 모든 컴포넌트가 최고로 안정적인 시스템이라면 변경이 불가능하다.
  • 컴포넌트 구조 설계시 불안정한 컴포넌트와 안정된 컴포넌트 모두 존재해야 한다.

SAP : 안정된 추상화 원칙

💡 컴포넌트는 안정된 정도만큼만 추상화되어야 한다.

고수준 정책을 어디에 위치시켜야 하는가?

  • 업무로직이나 아키텍처와 관련된 결정에는 변동성이 작아야 하므로, 시스템에서 고수준 정책을 캡슐화하는 소프트웨어는 반드시 안정된 컴포넌트(I=0)에 위치해야 한다. 불안정한 컴포넌트(I=1) 는 반드시 변동성이 큰 소프트웨어, 즉 쉽고 빠르게 변경할 수 있는 소프트웨어만을 포함해야 한다. 그러나 고수준 정책을 안정된 컴포넌트에 위치시키면, 그 정책을 포함한 소스 코드는 수정하기가 어려워져 시스템 전체 아키텍처의 유연성을 잃을 수 있다.
  • 이러한 문제는 개방 페쇄 원칙(OCP)를 통해 컴포넌트가 최고로 안정된 상태이면서도 동시에 변경에 충분히 대응할 수 있을 정도로 유연하게 만들 수 있다.
    • OCP에서는 클래스를 수정하지 않고도 확장이 충분히 가능할 정도로 클래스를 유연하게 만들 수 있으며, 구체적으로는 추상 클래스를 통해 이 원칙을 실제 구현할 수 있다.

안정된 추상화 원칙(Stable Abstract Principle)

  • 안정된 추상화 원칙은 안정성추상화 정도 사이의 관계를 정의한다.
  • 또한 이 원칙은 안정된 컴포넌트는 추상 컴포넌트여야 하며, 이를 통해 안정성이 컴포넌트를 확장하는 일을 방해해서는 안 된다고 말한다. 다른 한편으로는 불안정한 컴포넌트는 반드시 구체 컴포넌트여야 한다고 말하는데, 컴포넌트가 불안정하므로 컴포넌트 내부의 구체적인 코드를 쉽게 변경할 수 있어야 하기 때문이다.
  • SDP와 SAP를 결합하면 결국 의존성은 추상화의 방향으로 향하게 된다.
profile
하루하루 꾸준히

0개의 댓글