IT/책

[Clean Architecture] 4부, 컴포넌트 원칙

Terriermon 2021. 12. 4. 03:24

12장, 컴포넌트

컴포넌트란? 배포 단위 ex) 자바의 jar

 

- 컴포넌트롤 서로 링크하여 실행 가능한 단일 파일로 생성 할 수 있음 ex) .exe, .dll

 

 

역사

... 일부 생략 ...

 

- 링커: 프로그래머가 느린 부분을 처리해주는 링크 과정 처리, 링크가 완료된 재배치 코드를 만듦 -> 로드 속도 향상

= 한 번 만들어둔 실행 파일을 언제나 빠르게 로드 가능

 

1980년대: 소스 모듈

.c -> .o 컴파일된 후, 링커로 전달되어 로드될 수 있는 실행파일로 만들어 짐

-> 컴파일은 빨랐지만, 링커에서 더 많은 시간이 걸리게 됨

 

1980년대 후반: 무어의 법칙의 등장으로 디스크가 작아지고 빨라짐

 

1990년대 후반: 프로그램 링크 속도가 줄어들고, .jar 파일 등 등장

 

현재: .jar를 기본 애플리케이션에 플러그인 형태로 배포

 

 

결론

- 소프트웨어 컴포넌트: 런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일

 

 

 

13장, 컴포넌트 응집도

어떤 클래스를 어느 컴포넌트에 포함시켜야 하는지에 따른 원칙

 

종류

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

 

2. CCP: 공통 폐쇄 원칙

 

3. CRP: 공통 재사용 원칙

 

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

재사용 단위는 릴리스 단위와 같다.

 

- 릴리스 번호가 없으면 재사용 컴포넌트들이 서로 호환되는 지 보증할 방법이 없음

 

- 새로운 릴리스가 나오면, 적절한 공지와 함께 릴리스 문서 작성도 되어야 함

 

- 단일 컴포넌트는 응집성 높은 클래스와 모듈로 구성되어야 함

 

 

CCP: 공통 폐쇄 원칙

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

 

- 단일 책임 원칙(SRP)를 컴포넌트 관점에서 다시 쓴 것

 

- 단일 컴포넌트는 변경의 이유가 여러개 있으면 안됨

> 변경이 단일 컴포넌트에서만 발생하면, 하나만 재배포 하면 됨

 

- 물리적/개념적으로 강하게 결합되어 항상 함께 변경하는 클래스는 하나의 컴포넌트에 속해야 함

 

 

CRP: 공통 재사용 원칙

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

 

- 같이 재사용되는 경향이 있는 클래스와 모듈을 같은 컴포넌트에 포함해야 함

 

- 의존성 최소화

 

- 인터페이스 분리 법칙(ISP)의 포괄적인 버전, 사용하지 않는 클래스는 가진 컴포넌트에 의존하지 말아라

 

 

결론

응집도에는 세 원칙이 서로 상충됨

 

- REP와 CCP: 포함

- CRP: 배제

 

- 그 사이에서 균형점을 잘 유지해야 함

 

 

 

14장, 컴포넌트 결합

개발 가능성과 설계 사이의 균형

 

 

ADP: 의존성 비순환 원칙

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

 

- 많은 개발자가 동일한 소스 파일을 수정하는 환경일 경우, 누군가의 수정으로 수정이 계속 늘어남

 

- 해결 방법: 주 단위 빌드, 의존성 비순환 원칙

 

 

주 단위 빌드

- 중간 규모의 프로젝트

 

- 모든 개발자가 일주일의 4일은 서로 신경쓰지 않음, 마지막 날 통합

 

- 통합이 커질수록 금요일 하루에 끝낼 수 없어서 어려워 짐

 

 

순환 의존성 제거

- 개발 환경을 릴리스 가능한 컴포넌트 단위로 분리 -> 단일 개발팀/개별 개발자가 책임

 

- 컴포넌트를 한 명이 맡아서 지속적으로 수정

 

- 다른 팀에 좌우되지 않음

 

- 어떤 컴포넌트에서 시작해도, 의존성 관계를 따라가면 최초의 컴포넌트로 갈 수 없음(비순환)

 

- 상향식으로 테스트 시, 의존성 파악이 명료하게 가능

 

- 순환이 생겼을 때는 순환 끊기 또는 흐트러짐(Jitters)으로 해결

> 흐트러짐: 요구사항이 변경되면서 컴포넌트 구조도 변경될 수 있다는 사실로 인해 의존성 구조는 서서히 흐트러지며 성장함

 

 

하향식(top-down) 설계

- 컴포넌트 구조는 하향식으로 설계 될 수 없음: 컴포넌트는 가장 먼저 설계 대상이 아니기 때문

 

- 변동성 격리

 

- 재사용 가능한 요소를 만드는 것(CRP) -> 순환이 발생하면 AdP가 적용되면서 의존성 그래프는 성장

 

 

SDP: 안정된 의존성 원칙

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

 

- 설계는 정적일 수 없음 -> 변동성을 지니도록 설계

 

 

안정성

- 변화 빈도와는 관련X

 

- 변경을 만들기 위해 필요한 작업량과 관련

> 수많은 컴포넌트가 의존을 하게 되면, 변경하기 어려워 짐

 

X는 안정적인 컴포넌트

- 변경하지 말아야 할 이유가 3개

 

- X는 세 컴포넌트를 책임짐

 

- X는 어디에도 의존하지 않아, X가 변경되도록 만들 수 있는 외적인 영향이 없음: 독립적

 

 

 

안정성 지표

컴포넌트로 들어오고 나가는 의존성 개수로 판단

 

- Fan-in: 안으로 들어오는 의존성, 컴포넌트 내부의 클래스에 의존하는 컴포넌트 외부의 클래스 개수를 나타냄

- Fan-out: 바깥으로 나가는 의존성, 컴포넌트 외부 클래스에 의존하는 컴포넌트 내부 클래스 개수를 나타냄

- I(불안정성): I = Fan-out / (Fan-in + Fan-out), I=0이면 최고로 안정적

 

코드에서 include를 나타냄

 

 

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

- 모든 컴포넌트가 변경이 불가능 하는 것은 바람직한 상황이 아님

 

- 의존성으로 인해 변경이 불가능하다면, DIP를 도입하여 문제를 해결

-> 새로운 인터페이스 생성하여 컴포넌트에 삽입

참고

 

추상 컴포넌트

- 추상 컴포넌트는 매우 안정적

 

 

SAP: 안정된 추상화 원칙

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

 

고수준의 정책은 어디에 위치?

- 자주 변경해서 안되는 소프트웨어(고수준, 정책 결정 등)

> 안정된 컴포넌트(I=0)에 위치

 

- 그러나 안정된 컴포넌트에 위치하면, 정책을 포함하는 소스 코드는 수정하기 어려워짐 (유연성 하락)

 

- 안정된 상태이면서 변경에 대응할 수 있는 유연한 것은? OCP(개방 폐쇄 원칙): 클래스를 수정하지 않고 확장

추상 클래스

 

 

안정된 추상화 원칙

- 안정된 추상화 원칙(SAP)은 안정성과 추상화(abstractness) 사이의 관계를 정의

 

- 안정된 컴포넌트는 추상 컴포넌트여야 하며, 안정성이 컴포넌트를 확장하는 일을 방해해서는 안됨

 

- DIP = SAP + SDP

 

 

배제구역과 주계열

배제구역

고통의 구역

- 매우 안정적이며 구체적

- 뻣뻣한 상태이기 때문에 확장이 불가능함

- 데이터 스키마, String 등 위치

 

쓸모없는 구역

- 어떤 컴포넌트에도 의존하지 않음 -> 쓸모 없음

 

 

주계열

- (1,0)과 (0,1)을 잇는 선분

- 너무 추상적이지도, 불안정하지도 않음

 

주계열과의 거리 D

- 책참고...어려움...