김동형수 개발기

클린 아키텍처 - 4부 : 컴포넌트 원칙 본문

책 스터디/[완료] 클린아키텍처

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

김동형수 2023. 7. 24. 23:58

12장 컴포넌트

컴포넌트는 시스템의 구성 요소로 배포할 수 있는 가장 작은 단위다.

잘 설계된 컴포넌트라면 반드시 독립적으로 배포 가능한, 따라서 독립적으로 개발 가능한 능력을 갖춰야 한다.

컴포넌트의 간략한 역사

프로그램과 라이브러리가 사용하는 메모리가 늘어날수록 단편화는 계속 될 수밖에 없었다.

 

재배치성

해결책은 재배치가 가능한 바이너리였다.

컴파일러는 재배치가 가능한 바이너리 안의 함수 이름을 메타데이터 형태로 생성하도록 수정되었다.

외부 정의를 로드할 위치가 정해지기만 하면 로더가 외부 참조를 외부 정의에 링크시킬 수 있게 된다.

링킹 로더 탄생

링커

링킹 로더의 등장으로 프로그래머는 프로그램을 개별적으로 컴파일하고 로드할 수 있는 단위로 분할할 수 있게 되었다.

링킹 로더가 너무 느려서 참을 수 없는 지경에 다다랐다.

링커는 링크가 완료된 재배치 코드를 만들어 주었고, 그 덕분에 로더의 로딩 과정이 아주 빨라졌다.

고수준 언어를 사용하기 시작

각 모듈을 컴파일하는 과정은 상대적으로 빨랐지만, 전체 모듈을 컴파일하는 일은 꽤 시간이 걸렸다.

프로그램을 성장시키는 속도보다 링크 시간이 줄어드는 속도가 더 빨라지기 시작

다수의 공유 라이브러리를 순식간에 서로 링크한 후 링크가 끝난 프로그램을 실행할 수 있게 되었다.

컴포넌트는 플러그인 아키텍처가 탄생

 

13장 컴포넌트 응집도

컴포넌트 응집도와 관련된 세 가지 원칙

  • REP : 재사용 / 릴리즈 등가 원칙
  • CCP : 공통 폐쇄 원칙
  • CRP : 공통 재사용 원칙

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

컴포넌트는 응집성 높은 클래스와 모듈들로 구성되어야 함을 뜻한다.

하나의 컴포넌트로 묶인 클래스와 모듈은 반드시 함께 릴리즈할 수 있어야 한다. 하나의 컴포넌트로 묶인 클래스와 모듈은 버전 번호가 같아야 하며, 동일한 릴리즈로 추적 관리되고 동일한 릴리즈 문서에 포함되어야 한다.

 

CCP :  공통 폐쇄 원칙

동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라. 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 분리하라.

 

공통 폐쇄 원칙에서도 마찬가지로 단일 컴포넌트는 변경의 이유가 여러 개 있어서는 안 된다고 말한다.

변경이 여러 컴포넌트 도처에 분산되어 발생하기보다는 단일 컴포넌트에서 발생하는 편이 낫다.

변경을 단일 컴포넌트로 제한할 수 있다면 해당 컴포넌트만 재배포 하면 된다.

 

함께 변경되는 클래스들은 하나의 컴포넌트에 속해야 한다.

작업량을 최소화 할 수 있다.

 

공통적인 변경에 대해서 클래스가 닫혀 있도록 설계

 

CCP는 컴포넌트 수준의 SRP다.

 

CRP : 공통 재사용 원칙

컴포넌트 사용자들은 필요하지 않는것에 의존하게 강요하지 말라.

 

CRP에서는 같이 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함해야 한다고 말한다.

CRP는 동일한 컴포넌트로 묶어서는 안되는 클래스가 무언지도 말해준다.

재컴파일, 재검증, 재배포를 해야 하는 가능성은 여전히 남아 있다. 사용되는 컴포넌트에서 발생한 변경은 사용하는 컴포넌트와는 전혀 관계없는 경우라도 말이다.

CRP는 강하게 결합되지 않은클래스들을 동일한 컴포넌트에 위치시켜서는 안 된다고 말한다.

CRP는 ISP의 포괄적인 버전이다.

 

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

REP와 CCP는 포함 원칙

CRP는 배제 원칙

프로젝트 초기에는 CCP가 REP보다 훨씬 더 중요한데, 개발 가능성이 재사용성보다 더욱 중요하기 때문이다.

프로젝트가 실제로 수행하는 일 자체보다는 프로젝트가 발전되고 사용되는 방법과 더 관련이 깊다.

 

시간이 흐름에 따라 프로젝트의 초점이 개발가능성에서 재사용성으로 바뀌고 그에 따라 컴포넌트를 구성하는 방식도 조금씩 흐트러지고 또 진화한다.

14장 컴포넌트 결합

ADP : 의존성 비순환 원칙

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

 

주 단위 빌드

첫 4일 동안은 서로를 신경쓰지 않는다. 개발자는 모두 코드를 개인적으로 복사하여 작업하며, 전체적인 기준에서 작업ㅇ르 어떻게 통합할지는 걱정하지 않는다. 그런 후 금요일이 되면 변경된 코드를 모두 통합하여 시스템에 빌드한다.

시간이 지나면, 팀은 빠른 피드백이 주는 장점을 잃는다.

 

순환 의존성 제거하기

컴포넌트가 새로 릴리즈되어 사용할 수 있게 되면 다른 팀에서는 새 릴리즈를 당장 적용할지를 결정

특정 컴포넌트가 변경 되더라도 다른 팀에 즉각 영향을 주지는 않는다.

의존성 구조에 순환이 있어서는 안 된다.

 

릴리즈에 영향받는 팀은 쉽게 찾을 수 있다. 의존성 화살표를 거꾸로 따라가면 된다.

 

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

순환이 생기면 컴포넌트를 분리하기가 상당히 어려워진다. 단위 테스트를 하고 릴리즈를 하는 일도 굉장히 어려워지며 에러도 쉽게 발생한다. 빌드 관련 이슈는 기하급수적으로 증가한다.

어떤 순서로 빌드해야 올바를지 파악하기가 상당히 힘들어진다.

 

순환끊기

컴포넌트 사이의 순환을 끊고 의존성을 다시 DAG(비순환 방향 그래프)로 원상복구하는 일은 언제라도 가능하다.

이를 위한 주요 메커니즘 두 가지

  • 의존성 역전 원칙을 적용한다.
  • 모두 의존하는 새로운 컴포넌트를 반환한다.

흐트러짐

요구사항이 변경되면 컴포넌트 구조도 변경될 수 있다. 애플리케이션이 성장함에 따라 흐트러지며 성장한다.

의존성 구조에 순환이 발생하는지 항상 관찰

 

하향식 설계

컴포넌트 구조는 하향식으로 설계될 수 없다.

컴포넌트 의존성 다이어그램은 애플리케이션의 기능을 기술하는 일과 거의 관련이 없고 애플리케이션의 가능성과 유지보수성을 보여주는 지도

컴포넌트 구조는 프로젝트 초기에 설계할 수 없다.

컴포넌트 의존성 그래프는 자주 변경되는 컴포넌트로부터 안정적이며 가치가 높은 컴포넌트를 보호하려는 아키텍트가 만들고 가다듬게 된다.

 

SDP : 안정된 의존성 원칙

더 안정된 쪽에 방향으로 의존하라

 

설계를 유지하다 보면 변경은 불가피하다.

의존하게 되면 변동성이 큰 컴포넌트도 결국 변경이 어려워진다.

안정된 의존성 원칙을 준수하면 변경하기 어려운 모듈이 변경하기 쉽게 만들어진 모듈에 의존하지 않도록 만들 수 있다.

 

안정성

안정성은 변경을 만들기 위해 필요한 작업량과 관련된다.

컴포넌트를 변경하기 어렵게 마드는 확실한 방법 하나는 수많은 컴포넌트가 해당 컴포넌트에 의존하게 만드는 것이다. 컴포넌트 안쪽으로 들어오는 의존성이 많아지면 상당히 안정적이라고 볼 수 있는데, 사소한 변경이라도 의존하는 모든 컴포넌트를 만족시키면서 변경하려면 상당한 노력이 들기 때문이다.

 

안정성 지표

  • Fan-in : 안으로 들어오는 의존성
  • Fan-out: 바깥으로 나가는 의존성
  • I - 불안정성 : I = Fan-out / (Fan-in + Fan-out)

의존성 방향으로 갈수록 I 지표 값이 감소해야 한다.

 

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

SDP를 위반하면 DIP를 도입하면 이 문제를 해결할 수 있다.

 

추상 컴포넌트

오로지 인터페이스만을 포함하는 컴포넌트

정적 타입 언어를 사용할 때 필요한 전략

동적 타입 언어는 필요하지 않다.

 

SAP : 안정된 추상화 원칙

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

 

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

시스템에서 고수준 정책을 캡슐화하는 소프트웨어는 반드시 안정된 컴포넌트에 위치해야 한다.

해답은 OCP, 클래스를 수정하지 않고도 확장 가능한 추상클래스다.

 

안정된 추상화 원칙

안정적인컴포넌트라면 반드시 인터페이스와 추상 클래스로 구성되어 쉽게 확장할 수 있어야 한다. 안정된 컴포넌트가 확장이 가능해지면 유연성을 얻게 되고 아키텍처를 과도하게 제약하지 않게 된다.

 

고통의 구역

데이터베이스 스키마가 한 예다.

구체적인 유틸리티 라이브러리

변동성이 없는 컴포넌트는 고통의 구역에 위치되었다 해도 해롭지 않다.

문제가 되는 경우 변동성이 있는 소프트웨어 컴포넌트다.

 

쓸모 없는 구역

최고로 추상적이지만, 누구도 그 컴포넌트에 의존하지 않기 때문

 

배제 구역 벗어나기

주계열에 위치한 컴포넌트 - 너무 추상적이지도 너무 불안정하지도 않다.

 

주계열과의 거리

주계열에일치하도록 설계되었다면 평ㄹ균과 분산은 0에 가까워진다.

분산을 통해 다른 컴포넌트에 비해 극히 예외적인 컴포넌트를 식별할 수 있다.

Comments