본문 바로가기
독서/클린 아키텍처

클린 아키텍처 4부. 컴포넌트 원칙

by yoon_seon 2024. 7. 21.
  • SOLID 원칙이 벽과 방에 벽돌을 배치하는 방법을 알려준다면, 컴포넌트 원칙은 빌딩에 방을 배치하는 방법이다.
  • 큰 빌딩과 마찬가지로 대규모 소프트웨어 시스템은 작은 컴포넌트들로 만들어진다.

 

12장. 컴포넌트


  • 컴포넌트는 시스템의 구성 요소로 배포할 수 있는 가장 작은 단위이다.(jar, gem, DLL)
  • 컴포넌트는 다양한 형태로 만들어질 수 있다.
    • 여러 컴포넌트를 서로 링크하여 실행 가능한 단일 파일로 생성할 수 있다.
    • 여러 컴포넌트를 묶어서 war 파일과 같은 단일 아카이브로 만들 수 있다.
    • 컴포넌트 각각을 jar와 같이 동적으로 로드할 수 있는 플러그인이나 실행 가능한 파일로 만들어 독립적으로 배포할 수도 있다.
  • 컴포넌트가 최종적으로 어떤 형태로 배포되든, 잘 설계된 컴포넌트라면 반드시 독립적으로 개발 가능해야 한다.

 

결론

  • 런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일이 이 책에서 말하는 소프트웨어 컴포넌트에 해당한다.
  • 여기까지 오는데 50년이 걸렸고, 과거에는 초인적인 노력을 들여야만 컴포넌트 플러그인 아키텍처를 적용할 수 있었다.
  • 이제는 기본으로 쉽게 사용할 수 있는 지점까지 다다랐다.

 

13장. 컴포넌트 응집도


  • 어떤 클래스를 어떤 컴포넌트에 포함시켜야 할지는 중요한 결정이므로 제대로 된 소프트웨어 엔지니어링 원칙이 필요하다.
  • 이 장에서는 컴포넌트 응집도와 관련된 3가지 원칙을 논의한다.
    • REP: 재사용 / 릴리스 등가 원칙(Reuse/Release Equivalence Principle)
    • CCP: 공통 폐쇄 원칙(Common Closure Principle)
    • CRP: 공통 재사용 원칙(Common Reuse Rrinciple)

 

REP: 재사용 / 릴리스 등가 원칙

  • 재사용 단위는 릴리스 단위와 같다.
    • 소프트웨어 컴포넌트가 릴리스 절차를 통해 추적 관리되지 않거나 릴리스 번호가 없다면 재사용할 수 없고, 하지도 않을 것이다.
    • 릴리스 번호가 없다면 재사용 컴포넌트들이 서로 호환되는지 보증할 방법이 없다.
    • 개발자들은 새로운 버전이 언제 출시되고 무엇이 변했는지를 알아야 한다.
  • 이 원칙을 소프트웨어 설계와 아키텍처 관점에서 보면 단일 컴포넌트는 응집성 높은 클래스와 모듈들로 구성되어야 함을 뜻한다.
    • 컴포넌트를 구성하는 모든 모듈은 서로 공유하는 중요한 테마나 목적이 있어야 한다.
    • 이를 색다른 시각으로 보면, 하나의 컴포넌트로 묶인 클래스와 모듈은 반드시 함께 릴리스할 수 있어야 한다.
    • 하나의 컴포넌트로 묶인 클래스와 모듈은 버전 번호가 같아야 하며, 동일한 릴리스로 추적 관리되고, 동일한 릴리스 문서에 포함되어야 한다.
  • REP 만으로 클래스와 모듈을 단일 컴포넌트로 묶는 방법을 제대로 설명하기는 어렵지만, 이 원칙 자체는 중요하다.
  • REP를 어기면 쉽게 발견할 수 있으며, REP의 약점은 CCP와 CRP로 보완할 수 있다.

 

CCP: 공통 폐쇄 원칙

  • 동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶고, 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 묶어라
    • 이 원칙은 단일 책임 원칙을 컴포넌트 관점에서 다시 쓴 것
  • 대다수의 애플리케이션에서 유지보수성은 재사용성보다 훨씬 중요하며, 코드가 변경되어야 한다면 단일 컴포넌트에서 발생해야 한다.(독립적인 배포)
  • 이를 통해 소프트웨어를 릴리스, 재검증, 배포하는 일과 관련된 작업량을 최소화할 수 있다.
  • CCP와 OCP의 유사점
    • OCP와 관련이 있는데, 발생 가능성이 있는 대다수의 동일한 변경에 대해서 클래스가 닫혀있도록 설계해야 한다.
    • CCP에서는 동일한 유형의 변경에 닫혀 있는 클래스들을 하나의 컴포넌트로 묶음으로써 OCP에서 얻은 교훈을 확대 적용한다.
  • CCP와 SRP와 유사점
    • SRP : 서로 다른 이유로 변경되는 메서드를 서로 다른 클래스로 분리하라
    • CCP : 서로 다른 이유로 변경되는 클래스를 서로 다른 컴포넌트로 분리하라

 

CRP: 공통 재사용 원칙

  • 컴포넌트 사용자들을 필요하지 않은 것에 의존하게 강요하지 말라
  • CRP도 클래스와 모듈을 어느 컴포넌트에 위치시킬지 결정할 때 도움이 된다.
  • 같이 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함해야 한다.
    • 개별 클래스가 단독으로 재사용되는 경우는 거의 없다.
    • 대체로 재사용 가능한 클래스는 재사용 모듈의 일부로써 해당 모듈의 다른 클래스와 상호작용하는 경우가 많다.
    • CRP에서는 이런 클래스들이 동일한 컴포넌트에 있어야 한다고 말한다.
  • CRP는 동일한 컴포넌트로 묶어서는 안 되는 클래스가 무엇인지 말해준다.
    • 어떤 컴포넌트가 다른 컴포넌트를 사용하면 두 컴포넌트 사이에는 의존성이 생겨난다.
    • 사용하는 컴포넌트가 사용되는 컴포넌트에서 단 하나의 클래스만 사용할 수 있지만, 그렇다고 해서 의존성은 약해지지 않으며 여전히 의존한다.
    • 이로 인해 사용되는 컴포넌트가 변경될 때마다 사용하지 않는 컴포넌트도 변경해야 할 가능성이 높다.
    • 그러므로 의존하는 컴포넌트의 모든 클래스에 대해 의존함을 확실히 인지해야 한다.
    • 그렇지 않다면 필요 이상으로 많은 컴포넌트를 재배포하느라 노력을 허비하게 된다.
  • CRP는 ISP의 포괄적인 버전이다.
    • ISP : 사용하지 않는 메서드가 있는 클래스에 의존하지 말라
    • CRP : 사용하지 않는 클래스를 가진 컴포넌트에 의존하지 말라

 

컴포넌트 응집도에 대한 균형 다이어그램

  • 3가지 원칙은 서로 상충되는데, REP와 CCP는 포함 원칙(컴포넌트를 크게 만듦)이고 CRP는 배제 원칙(컴포넌트를 작게 만듦)이다.
  • 뛰어난 아키텍트는 3가지 원칙들이 균형을 이루는 방법을 찾아야 한다.
  • 아래의 균형 다이어그램으로 어떻게 상호작용하는지 보여준다.

  • 각 변은 반대쪽 꼭짓점에 있는 원칙을 포기했을 때 감수해야 할 비용을 나타냄
    • CCP를 포기하면, 사소한 변경이 생겼을 때 너무 많은 컴포넌트에 영향이 미침
    • CRP를 포기하면 불필요한 릴리스가 너무 빈번해짐
    • REP를 포기하면 재사용이 어려워짐
  • 뛰어난 아키텍트라면 이 균형 삼각형에서 개발팀이 현재 관심을 기울이는 부분을 충족시키는 위치를 찾아야 하며, 시간이 흐르면서 개발팀이 주의를 기울이는 부분 역시 변한다는 사실도 이해하고 있어야 한다.
  • 프로젝트의 컴포넌트 구조는 시간과 성숙도에 따라 변화한다.
    • 일반적으로 프로젝트는 삼각형의 오른쪽에서 시작하는 편이며, 이때는 오직 재사용성만 희생하면 된다.
    • 프로젝트가 성숙해지면 프로젝트는 삼각형에서 점차 왼쪽으로 이동한다.

 

결론

  • 어느 클래스를 묶어서 컴포넌트로 만들지 결정할 때, 재사용성과 개발 가능성이라는 상추 하는 힘을 반드시 고려해야 한다.
  • 이들 사이에서 애플리케이션의 요구에 맞게 균형을 잡는 일은 중요하며, 이 균형점은 거의 항상 유동적이다.
  • 즉, 두 힘을 현재 상황에 맞게 잘 분배했더라도, 내년이 되면 맞지 않을 수 있다.
  • 결과적으로 시간의 흐름에 따라 프로젝트의 초점이 개발 가능성에서 재사용성으로 바뀌고, 컴포넌트의 구성 방식도 조금씩 흐트러지고 또 진화한다.

 

 

14장. 컴포넌트 결합


컴포넌트 구조와 관련된 아키텍처를 침범하는 힘은 기술적이며, 정치적이고, 가변적이다.

 

ADP: 의존성 비순환 원칙

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

  • ‘숙취 증후군’은 많은 개발자가 동일한 소스 파일을 수정하는 환경에서 발생한다.
    • 숙취 증후군 : 이 책에서는 본인이 작업했던 결과물이 의존하고 있던 무언가를 타인이 수정해서 본인의 결과물이 동작하지 않는 현상이라고 말한다.
  • ‘숙취 증후군’의 해결책으로 두 가지 방법이 있다.
    • 주 단위 빌드
    • 의존성 비순환 원칙

주 단위 빌드(Weekly Build)

  • 모든 개발자가 4일간 서로를 신경 쓰지 않고, 금요일에 변경된 코드를 모두 통합하여 시스템을 빌드한다.
  • 4일 동안 개발자를 고립된 세계에서 살 수 있게 보장하지만, 프로젝트가 커질수록 프로젝트 통합 일정은 지연된다.
  • 결국 빌드 일정 지연, 통합과 테스트를 수행하기가 점점 더 어려워지고, 팀은 빠른 피드백이 주는 장점을 잃는다.

순환 의존성 제거하기

  • 개발 환경을 릴리스 가능한 컴포넌트 단위로 분리한다.
  • 이를 통해 컴포넌트는 개별 개발자 또는 단일 개발팀이 책임질 수 있는 작업 단위가 된다.
  • 개발자가 해당 컴포넌트가 동작하도록 만든 후, 릴리스하여 다른 개발자가 사용할 수 있도록 만든다.
    • 담당 개발자는 이 컴포넌트에 릴리스 번호를 부여하고, 다른 팀에서 사용할 수 있는 디렉터리로 이동시킨 후 자신만의 공간에서 컴포넌트를 지속적으로 수정한다.
  • 따라서 특정 컴포넌트가 변경되어도 다른 팀에 영향을 주지 않는다.
  • 이는 단순하며 합리적이어서 널리 사용되지만 컴포넌트 사이의 의존성 구조를 반드시 관리해야 한다.
  • 의존성 구조에 순환이 있어서는 안 되며 컴포넌트 간의 의존성은 비순환 방향 그래프(DAG)여야 한다.

  • Presenters를 수정하면 의존을 하고 있는 View와 Main 컴포넌트는 영향을 받게 된다.
  • Main가 릴리스 되더라도 이로 인해 영향을 받는 컴포넌트가 전혀 없다.
  • Presenter 컴포넌트를 테스트한다면 Interactors와 Entities를 이용하여 빌드할 수 있고, 나머지 컴포넌트는 영향이 없다.
  • 이처럼 구성요소 간 의존성을 파악하고 있으면 시스템을 빌드하는 방법을 알 수 있다.

 

순환이 컴포넌트 의존성 그래프에 미치는 영향

  • 새로운 요구사항으로 Entites에 포함된 클래스 하나가 Authorizer에 포함된 클래스 하나를 사용하도록 변경한다면 순환 의존성이 발생한다.

  • Database를 릴리스하려면 Entities, Authorizer, Interactors 컴포넌트와 반드시 호환되어야 한다.
  • Entities, Authorizer, Interactors는 사실상 하나의 거대한 컴포넌트가 되어 버리고, 각 개발자들이 서로에게 얽매이게 되어 항상 동일한 릴리스를 사용해야 한다.
  • 모듈의 개수가 많아짐에 따라 빌드 관련 이슈는 기하급수적으로 증가한다.
  • 컴포넌트를 어떤 순서로 빌드해야 올바를지 파악하기가 힘들어져서 올바른 순서라는 것 자체가 없게 된다.

 

순환 끊기

컴포넌트 사이의 순환을 끊고 의존성을 DAG로 원상 복구가 가능하다.

1. 의존성 역전 원칙(DIP)

  1. User가 필요로 하는 메서드를 제공하는 인터페이스를 생성하고 Entities에 위치시킨다.
  2. Authorizer에서는 이 인터페이스를 상속받는다.
    • 최종적으로 Entities와 Authorizer 사이의 의존성을 역전시켜 순환이 끊긴다.

 

2. 새로운 컴포넌트 생성

  1. Entities와 Authorizer가 모두 의존하는 새로운 컴포넌트를 만든다.
  2. 이후 두 컴포넌트가 모두 의존하는 클래스들을 새로운 컴포넌트로 이동시킨다.

 

흐트러짐(Jitters)

  • 순환 끊기의 새로운 컴포넌트 생성 해결책에서 시사하는 바는 요구사항이 변경되면 컴포넌트 구조도 변경될 수 있다는 사실이다.
  • 실제로 애플리케이션이 성장함에 따라 컴포넌트 의존성 구조는 서서히 흐트러지며 또 성장한다.
  • 따라서 의존성 구조에 순환이 발생하는지 항상 관찰해야 하며, 순환이 발생하면 어떤 식으로든 끊어야 한다.
  • 이 말은 때론 새로운 컴포넌트를 생성하거나 의존성 구조가 더 커질 수도 있음을 의미한다.

 

하향식(top-down) 설계

  • 컴포넌트는 시스템에서 가장 먼저 설계할 수 있는 대상이 아니며, 컴포넌트 구조는 하향식으로 설계될 수 없다.
    • 컴포넌트 의존성 다이어그램은 애플리케이션의 기능과 거의 관련이 없고 애플리케이션의 빌드 가능성과 유지보수성을 보여주는 지도와 같다.
    • 빌드 및 유지보수할 소프트웨어가 없다면 지도 또한 필요 없으므로 컴포넌트 구조는 프로젝트 초기에 설계될 수 없다.
  • 구현과 설계가 이뤄지는 프로젝트 초기에 모듈들이 점차 쌓이게되면, 의존성 관리에 대한 요구가 늘어난다.
    • 변경되는 범위가 시스템의 가능한 한 작은 일부로 한정되기를 원한다.
    • 그래서 단일 책임 원칙(SRP)과 공통 폐쇄 원칙(CCP)에 관심을 갖게 되고, 이를 적용해 함께 변경되는 클래스는 같은 위치에 배치시킨다.
    • 의존성 구조와 관련된 최우선 관심사는 변동성을 격리하는 일이다.
  • 애플리케이션이 성장함에 따라 재사용 가능한 요소를 만드는 일에 관심을 기울이기 시작한다.
    • 이 시점이 되면 컴포넌트를 조합하는 과정에서 공통 재사용 원칙(CRP)이 영향을 미치기 시작한다.
    • 순환이 발생하면 ADP가 적용되고, 컴포넌트 의존성 그래프는 흐트러지고 또 성장한다.
  • 아무런 클래스도 설계하지 않은 상태에서 컴포넌트 의존성 구조를 설계하려고 한다면 실패하기 쉽다.
    • 공통 폐쇠와 재사용 요소를 알지 못하고, 컴포넌트를 생성할 때 순환 의존성이 발생할 것이다.
    • 따라서 컴포넌트 의존성 구조는 시스템의 논리적 설계에 발맞춰 성장하고 진화해야 한다.

 

SDP: 안정된 의존 원칙

안정성의 방향으로(더 안정화된 쪽에) 의존하라.

  • 컴포넌트 중 일부는 변동성을 지니도록 설계되는데, 변경이 쉽지 않은 컴포넌트가 변동이 예상되는 컴포넌트에 의존해서는 절대로 안 된다.
  • 한번 의존하게 되면 변동성이 큰 컴포넌트도 변경이 결국 어려워진다.
  • 변경하기 쉽게 모듈을 설계해도, 누군가가 의존성을 매달아 버리면 변경하기 어려운 모듈이 된다.
  • 이 문제를 안정된 의존성 원칙(SDP)을 준수하면 변경하기 어려운 모듈이 쉽게 만들어진 모듈에 의존하지 않도록 만들 수 있다.

 

안정성

  • 안정성은 변화가 발생하는 빈도와는 직접적인 관련이 없고, 변경을 위한 작업량과 관련된다.
  • 안정적이라는 것은 변경을 위해 상당한 수고를 감수해야 한다는 것
    • 소프트웨어 컴포넌트를 변경하기 어렵게 만드는 데는 많은 요인이 존재한다.(크기, 복잡도, 간결함)
    • 컴포넌트를 변경하기 어렵게 만드는 확실한 방법 중 하나는 수많은 다른 컴포넌트가 해당 컴포넌트에 의존하게 만드는 것
    • 컴포넌트 안쪽으로 들어오는 의존성이 많아지면 상당히 안정적이라고 볼 수 있다.
    • 사소한 변경이라도 의존하는 모든 컴포넌트를 만족시키면서 변경하려면 상당한 노력이 들기 때문이다.

 

안정한 컴포넌트

  • 3개의 컴포넌트가 X에 의존하며 X 컴포넌트를 변경하면 안되는 이유는 3가지나 된다.
  • 이 경우 X는 3가지 컴포넌트를 책임진다고 한다.
  • 반대로 X는 어디에도 의존하지 않으므로 X가 변경되도록 만들 수 있는 외적인 영향이 없다.
  • 이 경우 X는 독립적이라고 한다.

 

불 안정한 컴포넌트

  • 어떤 컴포넌트도 Y에 의존하지 않는다.
  • 이 경우 Y는 책임성이 없다고 한다.
  • Y는 3가지 컴포넌트에 의존하므로 변경이 발생할 수 있는 외부 요인이 3가지 이다.
  • 이 경우 Y는 의존적이라 한다.

 

안정성 지표

  • 컴포넌트로 들어오고 나가는 의존성 개수를 세어보면 컴포넌트 안정성을 측정할 수 있다.
    • Fan-in : 안으로 들어오는 의존성, 컴포넌트 내부의 클래스에 의존하는 컴포넌트 외부의 클래스 개수
    • Fan-out : 밖으로 나가는 의존성, 컴포넌트 외부의 클래스에 의존하는 컴포넌트 내부의 클래스 개수
    • I(불안정성) : Fan-out / (Fan-in + Fan-out)로 계산하며, [0,1] 범위의 값을 갖는다.
      • I 가 1 이면 최고로 불안정한 컴포넌트라는 의미
      • I 가 0 이면 최고로 안정된 컴포넌트라는 의미
  • I 값이 1인 경우 = 최고로 불안정된 컴포넌트
    • 어떤 컴포넌트도 해당 컴포넌트에 의존하지 않지만, 해당 컴포넌트는 다른 컴포넌트에 의존한다.
    • 이 컴포넌트는 책임성이 없으며 의존적이기에 컴포넌트가 가질 수 있는 최고로 불안정한 상태다.
    • 의존하는 컴포넌트가 없어서 해당 컴포넌트를 변경하지 말아야 할 이유가 없다.
    • 반대로 컴포넌트가 다른 컴포넌트에 의존한다는 사실은 언젠가 컴포넌트를 변경할 이유가 있다는 뜻
  • I 값이 0인 경우 = 최고로 안정한 컴포넌트
    • 해당 컴포넌트에 의존하는 다른 컴포넌트가 있지만, 해당 컴포넌트는 다른 컴포넌트에 의존하지 않는다.
    • 이 컴포넌트는 다른 컴포넌트를 책임지며 독립적이기에 컴포넌트가 가질 수 있는 최고로 안정된 상태다.
    • 자신에게 의존하는 컴포넌트가 있으므로 해당 컴포넌는 변경하기 어렵다.
    • 반대로 해당 컴포넌트를 변경하도록 강제하는 의존성을 갖지 않는다.
  • 즉, 의존성 방향으로 갈수록 I 지표 값이 감소해야 한다.

 

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

  • 모든 컴포넌트가 최고로 안정적인 시스템이라면 변경이 불가능하고, 이는 바람직한 상황이 아니다.
  • 우리가 기대하는 컴포넌트 구조는 불안정한 컴포넌트와 안정한 컴포넌트가 모두 존재하는 상태다.

 

이상적인 구성

  • 위 구성은 변경 가능한 컴포넌트가 보이고, 아래의 안정된 컴포넌트에 의존한다.
  • 관례적으로 위쪽에 변경 가능한 컴포넌트, 아래는 안정된 컴포넌트를 둔다.
  • 위로 향하는 화살표가 있으면 SDP를 위배하는 상태가 된다.(위 구성은 없음)

 

SDP를 위배한 구성

  • Flexible은 변경하기 쉽도록 설계한 컴포넌트다.
  • 우리는 Flexible이 불안정한 상태(변경 가능한 컴포넌트)이기를 바라지만, Stable에서 Flexible에 의존성을 걸게 되면 SDP를 위배하게 된다.
  • Stable의 I 지표는 Flexible의 I 지표보다 작고, 결국 Flexible은 변경이 어렵게 되었다.
  • Flexible을 변경하려면 Stable과 Stable에 의존하는 나머지 컴포넌트에도 조치를 취해야 한다.

 

  • 이 문제를 해결하려면 Stable의 Flexible에 대한 의존성을 어떤 식으로든 끊어야 한다.
  • DIP를 도입하면 해결할 수 있다.

 

  • US라는 인터페이스를 생성하고 이를 UServer 컴포넌트에 넣고, C가 해당 인터페이스를 구현하도록 만든다.
  • 이를 통해 Flexible에 대한 Stable의 의존성을 끊고, 두 컴포넌트는 모두 UServer에 의존하도록 강제한다.
  • UServer는 매우 안정적인 상태이며(I=0) Flexible은 불안정성(I=1)를 유지할 수 있고, 모든 의존성은 I가 감소하는 방향으로 향함
    • 오로지 인터페이스만을 포함하는 컴포넌트(UServer)를 생성하는 방식이 이상하게 보일 수도 있다.
    • 하지만 자바와 같은 정적 타입 언어에서는 이 방식이 흔히 사용되며 꼭 필요한 전략으로 알려져 있다.
    • 이러한 추상 컴포넌트는 상당히 안정적이며, 따라서 덜 안정적인 컴포넌트가 의존할 수 있는 이상적인 대상이다.

 

SAP: 안정된 추상화 원칙

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

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

  • 시스템에서는 고수준 아키텍처나 정책 결정과 같이 자주 변경해서는 안되는 소프트웨어도 있다.
  • 따라서 시스템에서 고수준 정책을 캡슐화하는 소프트웨어는 반드시 안정된 컴포넌트에 위치해야하고 불안정한 컴포넌트는 쉽고 빠르게 변경할 수 있는 소프트웨어만 포함해야 한다.
  • 하지만 고수준 정책을 안정된 컴포넌트에 위치시키면, 그 정책을 포함하는 소스 코드는 수정하기가 어려워져서 시스템 전체 아키텍처가 유연성을 잃는다.
  • 컴포넌트가 최고로 안정된 상태이면서 변경에 대응할 수 있도록 유연하게 만들라면 OCP를 지켜야 한다.
  • OCP는 클래스를 수정하지 않고도 확장이 출분히 가능할 정도로 클래스를 유연하게 만들 뿐만 아니라 바람직한 방식이다.
  • 이 원칙을 준수하는게 바로 추상 클래스다.

 

안정된 추상화 원칙

  • 안정된 추상화 원칙은 안정성과 추상화 정도 사이의 관계를 정의한다.
    • 안정된 컴포넌트가 추상 컴포넌트여야 하고, 이를 통해 안정성이 컴포넌트를 확장하는 일을 방해해서는 안 된다
    • 컴포넌트 내부의 코드를 쉽게 변경할 수 있는 불안정한 컴포넌트는 반드시 구체 컴포넌트여야 한다.
  • 따라서 안정적인 컴포넌트라면 반드시 인터페이스와 추상 클래스로 구성되어 확장이 쉬워야 한다.
  • 안정적인 컴포넌트가 확장이 가능해지면 유연성을 얻고 아키텍처를 과도하게 제약하지 않게 된다.
  • SAP와 SDP를 결합하면 컴포넌트에 대한 DIP와 마찬가지다.
    • SDP는 의존성이 안정성의 방향으로 향해야 하고
    • SAP는 안정성이 결국 추상화를 의미 한다고 말하기 때문
    • 따라서 의존성은 추상화의 방향으로 향하게 된다.
    • 하지만 DIP는 클래스에 대한 원칙이며 클래스의 경우 중간은 존재하지 않는다.(추상적이거나, 아니거나)
    • SDP와 SAP의 조합은 컴포넌트에 대한 원칙이며, 컴포넌트는 어떤 부분은 추상적이면서 다른 부분은 안정적일 수 있다.

 

결론

  • 의존성 관리 지표는 설계의 의존성과 추상화 정도를 내가 훌륭한 패턴이라고 생각하는 수준에 얼마나 잘 부합하는지를 측정한다.
  • 경험을 통해 좋은 의존성도 있지만 좋지 않은 의존성도 있다는 사실, 하지만 지표는 신이 아니다.
  • 지표는 그저 임의로 결정된 표준을 기초로 한 측정값에 지나지 않고, 아무리 해도 불완전하다.
  • 하지만 이들 지표로부터 무언가 유용한 것을 찾을 수 있기를 바람.

 


모든 내용은 [클린 아키텍처] 서적의 정리한 내용이며, 망나니 개발자님의 블로그에서 정리 방법을 참고했습니다.

 

클린 아키텍처: 소프트웨어 구조와 설계의 원칙 | 로버트 C. 마틴 - 교보문고

클린 아키텍처: 소프트웨어 구조와 설계의 원칙 | 살아있는 전설이 들려주는 실용적인 소프트웨어 아키텍처 원칙 소프트웨어 아키텍처의 보편 원칙을 적용하면 소프트웨어 수명 전반에서 개발

product.kyobobook.co.kr

 

[개발서적] 클린 아키텍처 4부 컴포넌트 원칙 - 내용 정리 및 요약

이번에는 로버트 C 마틴의 클린 아키텍처를 읽은 내용을 정리해보도록 하겠습니다. 개인적인 설명은 기울임으로 표시해두었으니, 읽으면서 참고하시면 될 것 같습니다. 0. 서론 [ 도입 ] SOLID 원

mangkyu.tistory.com

 

댓글