IT Book Summary/Clean Architecture

04 컴포넌트 원칙 -2

laughcryrepeat 2021. 3. 1. 22:36

 

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

  • REP: The Reuse/Release Equivalence Principle
  • CCP: The Common Closure Principle
  • CRP: The Common Reuse Principle

 

13장 컴포넌트 응집도 Component Cohesion

 

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

 

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

 

릴리즈 번호가 없으면 재사용 컴포넌트들이 서로 호환되는지 보증할 수 없음.

하나의 컴포넌트로 묶인 클래스와 모듈은 반드시 함께 릴리스 가능해야 함.

 

CCP: 공통 폐쇄 원칙

 

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

서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트에 분리

단일 컴포넌트는 변경의 이유가 여러개 있어서는 안된다.

 

유지보수성이 재사용성보다 중요하므로,

코드가 변경되어야할때 변경이 한 컴포넌트에 있는게 낫다.

--> 같은 이유로 변경될 가능성이 있는 클래스는 한곳으로 모으자.

 

ocp에서 말하는 '클래스가 변경에는 닫혀있고 확장에는 열려있어야 한다' 는 원칙.

동일한 유형의 변경에 대해 닫혀 있는 클래스들을 하나의 컴포넌트로 묶어 ocp 원칙을 확대 적용.

 

 

CRP: 공통 재사용 원칙

 

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

 

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

강하게 결합되지 않는 클래스들을 동일한 컴포넌트에 위해해서는 안됨.

 

crp는 인터페이스 분리원칙 ISP의 포괄적 버전이다.

필요하지 않은것에 의존하지 마라

 

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

 

Cohesion principle tension diagram

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

일반적으로 프로젝트는 삼각형의 오른쪽에서 시작해 점차 왼쪽으로 이동.

프로젝트 컴포넌트 구조는 시간과 성숙도에 따라 변한다.

 

결론

REP, CCP, CRP 사이에서 애플리케이션의 요구에 맞게 균형을 잡는일이 중요하다.

균형점은 항상 유동적이고 시간 흐름에 따라 컴포넌트를 구성하는 방식도 진화한다.

 


14장 컴포넌트 결합

 

ADP: 의존성 비순환 원칙

 

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

 

큰프로젝트의 여러명의 개발자가 협업하는 경우 다른사람의 코드수정으로 자신의 코드가 동작하지 않는 경우가 종종 있다.

이 경우의 두가지 해결책은 '주 단위 빌드' weekly build, '의존성 비순환 원칙' Acyclic Dependencies Principle 이다.

 

주 단위 빌드 weekly build

 

모든 개발자는 일주일의 첫 4일은 서로 신경쓰지 않는다. 금요일에 변경된 코드를 모두 통합하여 시스템을 빌드한다.

하지만 점점 통합에 걸리는 시간이 길어지고 팀은 빠른 피드백을 잃는 단점이 있다.

 

의존성 비순환 원칙 Acyclic Dependencies Principle

 

개발 환경을 분리하여 컴포넌트를 개별 개발자, 단일 개발팀이 책임질 수 있는 작업단위로 분리한다.

개발자는 자신만의 공간에서 해당 컴포넌트를 수정하고 나머지 개발자는 릴리스된 버전을 사용한다.

따라서 통합은 작고 점진적으로 이루어진다.

 

Typical Component Diagram

이 구조에서는 어느 컴포넌트에서 시작해도 의존성 관계에서 최초 컴포넌트로 돌아가지 않는다. 즉 비순환 방향 그래프 이다.

시스템 전체를 릴리스 해야하면 절차는 상향식으로 진행된다.

 

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

 

Entities의 User 클래스가 Authorizer의 Permissions 클래스를 사용한다면

의존성 그래프에 순환이 생긴다.

순환이 생기면 순서가 없어 자바처럼 컴파일된 바이너리 파일에서 선언문을 읽어들이는 언어의 경우 문제가 된다.

 

순환 끊기

 

1. 의존성 역전 원칙 사용.

 

의존성 역전

 

User가 필요로 하는 메서드를 제공하는 인터페이스를 생성하여 Entities에 위치시키고,

Authorizer가 이 인터페이스를 상속받게 하여 의존성을 역전 시킬수 있다.

 

2. Entities와 Authorizer가 모두 의존하는 컴포넌트 생성.

흐트러짐

요구사항이 변경되면 새로운 컴포넌트를 생성하거나 의존성 구조가 커지거나, 컴포넌트 구도도 변경될 수 있다.

 

하향식 top-down 설계

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

컴포넌트는 시스템에서 가장 먼저 설계할 수 있는 대상이 아니며, 시스템이 성장하면서 함께 진화 한다.

컴포넌트 의존성 다이어그램은 애플리케이션의 빌드가능성, 유지보수성을 보여주는 map과 같다.

 

의존성구조와 관련된 최대 관심사는 변동성을 격리하는 일.

 

SDP: 안정된 의존성 원칙

 

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

 

컴포넌트중 일부는 변동성을 지니도록 설계된다.

변경이 쉽지않은 컴포넌트가 변동이 예상되는 컴포넌트에 의존하게 만들면 안됨.

 

 

안전성

안정성은 변화가 발생하는 빈도와 직접적 관련이 없다.

컴포넌트를 변경하기 어렵게 만드는 것ㅈ우 하나는 다른 컴포넌트가 해당 컴포넌트에 의존하게 만드는 것.

 

 

X는 안정된 컴포넌트, Y는 불안정한 컴포넌트 (변경이 발생할 수 있는 외부 요인이 세가지)

 

안정성 지표

 

컴포넌트 안정성의 측정. 계산.

  • Fan-in : 안으로 들어오는 의존성.
  • Fan-out : 바깥으로 나가는 의존성.
  • I(불안정성) : I = Fan-out / (Fan-in + Fan-out)
    0이면 최고 안정된 컴포넌트, 1이면 최고 불안정 컴포넌트.

예제

 

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

불안정한 컴포넌트와 안정된 컴포넌트의 공존

 

이상적인 구성

만약 Stable 컴포넌트가 Flexible 컴포넌트를 의존하는 상황이 발생하면 그 의존관계를 끊어야 한다.

C가 US 인터페이스를 구현하도록 한다.

US 인터페이스를 생성한 후 UServer 컴포넌트에 넣고, U가 사용하는모든 메서드가 선언되도록 만든다.

따라서 두 컴포넌트 모두 UServer에 의존하도록 하고 UServer를 안정적 상황으로 만든다.

 

추상 컴포넌트

 

추상 컴포넌트는 상당히 안정적이며 덜 안정적 컴포넌트가 의존할 수 있게 만드는 이상적 대상이다.

 

 

SAP: 안정된 추상화 원칙

 

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

 

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

 

고수준 아키텍처나 정책 결정과 관련된 것은 자주 변경해서는 안되는 소프트웨어이다.

하지만 그 정책을 포함하는 소스코드는 수정이 어려워진다.

해결책은 개방폐쇄원칙 OCP

추상 클래스

 

안정된 추상화 원칙 Stable Abstractions Principle, SAP

 

안정성과 추상화 정도 사이의 관계를 정의

 

안정된 컴포넌트는 추상, 불안정한 컴포넌트는 구체.

컴포넌트는 어떤 부분은 추상저이면서 다른 부분은 안정적일 수 있다.

 

 

추상화 정도 측정하기

 

  • Nc: 컴포넌트의 클래스 개수
  • Na: 컴포넌트의 추상 클래스와 인터페이스의 개수
  • A: 추상화 정도 A =Na/Nc

A가 0이면 추상클래스가 존재하지 않음, 1이면 오로지 추상클래스만 포함.

 

주계열

 

A/I 그래프 상 컴포넌트가 위치할 수 있는 합리적인 지점을 정의하는 점의 궤적.

이 궤적은 컴포넌트가 절대 위치해서 안되는 영역을 찾는 방식으로 추론 가능.

 

Zone of Exclusion

 

고통의 구역

 

(0.0) 주변 구역. 매우 안정적이며 구체적.

확장 변경하기 힘드므로 배제해야할 구역.

 

하지만 Util이나 디비 인터페이스는 변동성이 거의 없으므로 해롭지 않음.

 

쓸모없는 구역

 

(1,1) 주변의 컴포넌트. 최고로 추상적이고 의존성이 없는 상태.

누구도 구현하지 않은채 남겨진것으로 쓸모없는 구역. 바람직하지 않음.

 

배제 구역 벗어나기

 

변동성이 큰 컴포넌트. 두 배제 구역에서 떨어뜨리자.

대다수의 컴포넌트가 두 종점에 위히하도록  할 때 가장 이상적.

 

주 계열과의 거리

 

  • D4: 거리. D = | A+I -1 |
    0이면 컴포넌트가 주계열 바로 위 위치. 1이면 멀리 위치

이 지표를 계산하여 컴포넌트가 주계열에 대체로 일치하도록 설계되었는지 산정 분석 가능.

 

컴포넌트 산점도
단일 컴포넌트에 대해 시간에 따른 D 값을 표시한 도표

 

 

결론

 

지표는 임의로 결정된 표준을 기초로 한 측정값.

하지만 이로부터 유용한 것. 설계의 의존성과 추상화 정도를 찾을 수 있다.