개성있는 개발자 되기

4부 컴포넌트 원칙 - (3) 컴포넌트 결합 본문

Web Development/Clean Architecture

4부 컴포넌트 원칙 - (3) 컴포넌트 결합

정몽실이 2020. 3. 15. 17:27

컴포넌트 구성방법을 앞장에서 살펴봤다면, 이번 장에서는 컴포넌트 사이의 관계를 설명한다.

 

ADP (Acyclic Dependency Policy) : 의존성 비순환 원칙

SDP (Stability Dependency Policy) : 안정된 의존성 원칙

SAP (Stablility Abstract Policy) : 안정된 추상화 원칙

 


1) ADP (Acyclic Dependency Policy) : 의존성 비순환 원칙

 

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

 

많은 개말자가 동일한 소스파일을 수정하는 환경에서 "Morning after Syndrome" 이 발생한다.

즉, 내가 잘 동작하도록 만들어 놓은 소스를 다음날 아침이 되보니 다른 사람이 수정해서 제대로 작동하지 않는 현상을 말한다. 

 

이 문제의 해결책은 개발 환경을 릴리스 가능한 컴포넌트 단위로 분리하는 것이다.

개발자가 컴포넌트A를 개발한 뒤, 릴리스하여 다른 개발자가 사용할 수 있도록 만든다. 다른 개발자는 새 릴리스A를 적용할 지 결정한다.

 

이 같은 작업 절차는 현재도 널리 사용되는 방식이다. (Maven Dependency 처럼) 하지만 이 절차가 성공적으로 동작하려면 컴포넌트 사이의 의존성 구조를 반드시 관리해야 한다. (반드시 분리되어 있어야 한다.)

 

 

위의 컴포넌트 다이어그램은 의존성이 비순환한다. 즉 흐름대로 따라가면 순환이 되지않고 End 된다.

Presenters 컴포넌트 개발자는 단순히 현재 사용중인 버전의 Interactors와 Entities를 이용해서 Presenters 자체 버전을 빌드하면 그만이다.

 

하지만 Entiteis 와 Authorizer 사이에 의존성이 발생해서 순환 의존성이 발생되면 어떻게 될까.

아까 독립적으로 빌드할 수 있었던 아키텍쳐가, 이제는 순환 의종성 때문에 본인이 엮인 모든 컴포넌트를 재 빌드해야하는 상황이 생긴다. 이처럼 순환이 생기면 컴포넌트를 분리하기가 상당히 어려워진다.

 

순환 끊기

 

  1. 의존성 역전 원칙(DIP)를 적용한다.
    추상적 컴포넌트인 인터페이스를 Entities와 Authorizer 사이에 두어서, 두 컴포넌트의 의존성을 끊는다.
  2. Entities와 Authorizer가 모두 의존하는 새로운 컴포넌트를 만든다.

Jitters

요구사항이 바뀌면 컴포넌트 구조도 변경될 수 있다. 의존성 구조는 서서히 Jitters되며 발전하므로, 아키텍쳐의 순환구조를 꼼꼼이, 정기적으로 관찰할 필요가 있다.

 

 

2) SDP (Stability Dependency Policy) : 안정된 의존성 원칙

 

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

 

→ 변경하기 어려운 모듈이 변경하기 쉽게 만들어진 모듈에 의존하지 않도록 만들어야 한다.

 

안정성

소프트웨어 컴포넌트를 변경하기 어렵게 만드는 확실한 방법은 수많은 다른 컴포넌트가 해당 컴포넌트에 의존하게 만드는 것이다.

왜냐하면, N개의 컴포넌트가 A컴포넌트에 의존하고 있다면, A컴포넌트는 N개의 컴포넌트를 책임지고 있기 때문에 쉽게 변경되지 못하기 때문이다.

 

I (불안정성) 지표 = Fan out(내가 의존하는 의존성개수) % (Fan in (나를 의존하는 의존성 개수) + Fan out)

I = 0이면 최고로 안정된 컴포넌트라는 뜻이다.

 

SDP에서 의존성 방향으로 갈수록 I 지표 값이 감소, 즉 더욱 안정적이어야 한다는 뜻을 가지고 있다.

 

추상 컴포넌트

안정성이 강한 Stable 컴포넌트가 변경이 잦은 Flexible 컴포넌트를 사용(의존)해야 한다면, 의존성을 끊기 위해 인터페이스를 생성하는 방향이 있을 수 있다.

이러한 추상 컴포넌트는 상당히 안정적이며, 따라서 덜 안정적인 컴포넌트가 의존할 수 있는 이상적인 대상이다.

 

3) SAP (Stablility Abstract Policy) : 안정된 추상화 원칙

 

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

 

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

 

변동성이 없는 정책을 캡슐화하는 소프트웨어는 반드시 안정된 컴포넌트(I=0)에 위치해야한다 하지만 소스코드는 수정하기가 어려워진다. 이때, 우리는 클래스를 수정하지 않고도 확장이 충분히 가능한 클래스를 사용하면 된다. 바로 추상클래스다.

 

| 안정된 추상화 원칙

 

안정된 컴포넌트는 추상 컴포넌트여야 하며, 이를 통해 안정성이 컴포넌트를 확장하는 일을 방해해서는 안된다고 말한다.

또한, 불안정한 컴포넌트는 반드시 구체 컴포넌트여야 하는데, 쉽게 변경할 수 있어야 하기 때문이다.

 

즉, SDP에서는 안정성이 결국 추상화를 의미한다고 말하기 때문에, 의존성은 추상화의 방향으로 향하게 된다.

 

| 추상화 정도 측정하기

 

A = 컴포넌트의 추상 클래스와 인터페이스의 개수 / 컴포넌트의 클래스 개수

 

A 지표가 0이면 추상클래스가 하나도 없다는 것이고, 1이면 오로지 추상 클래스만은 포함한다는 뜻이다.

 

안정성(I)와 추상화 정도(A) 사이의 관계를 그래프로 표현하면 아래와 같다.

 

I/A 그래프를 통해, 우리의 컴포넌트가 잘 설계되어 있는지 검증해볼 수 있다.

 

- 고통의 구역

(0,0) 주변 구역에 위치한 컴포넌트는 매우 안정적이며 구체적이다.

추상적이지 않기 때문에 확장할 수 없고, 안정적이라 변경하기도 상당히 어렵다.

 

ex) 데이터 스키마, 유틸리티 라이브러리 등, 변동성이 없는 컴포넌트라면 이 구간에 있어도 되지만, 변동성이 많은 컴포넌트라면 고통의 구간이 될것이다.

 

- 쓸모없는 구역

(1,1) 주변 구역에 있는 컴포넌트는 최고로 추상적이지만, 어떠한 컴포넌트에도 의존하지 않아서 쓸모가 없다.

이러한 엔터티는 누구도 구현하지 않은 채 남겨진 추상 클래스인 경우가 많다.

 

결론

좋은 아키텍쳐를 설계하고자 하면 이러한 배제구역으로부터 떨어지고, 바람직한 구간이인 주계열의 두 종점에 위치하도록 만들면 된다.

 

이렇게 의존성 관리 지표는 설계의 의존성과 추상화 정도가 내가 "훌륭한" 패턴이라고 생각하는 수준에 얼마나 잘 부합하는지를 측정한다.

Comments