본문 바로가기
프로그래밍/클린 아키텍처

[클린아키텍처] 4부. 컴포넌트 응집도

by 2KB 2021. 3. 21.

어떤 클래스를 어떤 컴포넌트에 포함시켜야 할지에 대해서는 아래와 같이 컴포넌트 응집도와 관련된 세가지 원칙이 존재한다.

 

REP: 재사용/릴리즈 등가 원칙(Reuse/Release Equivalence Principle)

CCP: 공통 폐쇄 원칙 (Common Closure Principle)

CRP: 공통 재사용 원칙(Common Reuse Principle)

 

응집도는 모듈 내부에 존재하는 구성 요소들 사이의 밀접한 정도를 나타낸다.

모듈 안의 구성요소들이 얼마나 서로간의 의존도가 높은지에 따라 평가된다.

즉, 응집도가 높다는 것은 꼭 필요한 구성요소들로만 이루어져 있다는 것이다.

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


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

현대의 개발자는 Maven, Gradle 과 같은 모듈 관리 도구를 사용하여 소프트웨어 재사용의 시대에 살고 있다.

생각해보자, Maven 이나 Gradle을 통해 관리되는 컴포넌트 라이브러리들이 릴리스가 추적되지 않으면 어떤 일이 발생하는가?

릴리스 번호(버져닝)가 부여되지 않는다면, 컴포넌트의 호환성을 보증할 방법이 없다.

따라서, 컴포넌트의 새로운 릴리스가 발생했을 경우에는 릴리스 번호와 함께 적절한 문서와 변경사항이 공지되어야 한다.

또한 컴포넌트 릴리스는 추적관리가 되어야 하기 때문에 단일 컴포넌트는 응집성 높은 클래스와 모듈로 구성하여 컴포넌트로 묶인 클래스와 모듈의 버전번호 또한 동일하게 관리해야 한다.

 

CCP: 공통 폐쇄 원칙


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

이 원칙은 앞서 나온 단일책임원칙(SRP)를 컴포넌트 관점에서 다시 쓴 것이다.

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

예를 들어 애플리케이션에서 코드의 수정이 필요할때, 애플리케이션을 이루고 있는 여러 컴포넌트들에서 수정이 발생 하는 것 보다는 단일 컴포넌트에서 수정이 발생하도록 하는 것이 유지보수성을 위해 훨씬 중요하다는 것이다.

따라서 CCP 원칙은 같은 이유로 변경될 가능성이 있는 클래스는 모두 한곳으로 묶을 것을 권한다.

또한 함께 변경되는 클래스들은 하나의 컴포넌트에 속해야 하고, 이를 통해 작업량을 최소화할 수 있게 된다.

CCP는 "폐쇄"라는 관점에서 개방폐쇄원칙(OCP)과도 밀접하게 관련이 있다.

이는 컴포넌트에 속한 클래스들은 대다수의 공통적인 변경에 대해서 닫혀 있도록 설계되어야 한다는 것이며

이렇게 작성된 컴포넌트들은 애플리케이션에서 변경이 발생하였을 때, 영향을 주는 컴포넌트들이 최소한으로 한정될 수 있도록 제한할 확률이 높아지게 된다.

 

CRP: 공통 재사용 원칙


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

공통 재사용 원칙은 같이 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함되어야 한다는 원칙이다.

대체로 재사용 가능한 클래스는 재사용 모듈의 일부로써 모듈내 다른 클래스와 상호작용 하는 경우가 많다.

따라서 이러한 클래스들은 동일한 컴포넌트에 포함되어야 하고, 이를 다르게 말하면, 컴포넌트 내부에서는 클래스들 사이에 수많은 의존성이 있으리라 예상할 수 있다. 이러한 의존성을 통해 서로 강하게 결합되어 있기에, 함께 재사용된다.

이러한 재사용이 컴포넌트 끼리로 확대되었을 때를 보자.

B라는 컴포넌트가 A라는 컴포넌트를 사용하게 되면, B는 A에 의존적인 컴포넌트가 된다.

A 컴포넌트내의 일부 클래스에만 의존하는것이 아니라, A컴포넌트에 속한 모든 클래스에 대해 B컴포넌트가 의존을 하게 됨으로서 필요하지 않은 것에 의존하게 되는 것이며, 결과적으로는 A 컴포넌트가 변경될 때마다 B 컴포넌트는 재컴파일, 재검증, 재배포를 해야될 가능성이 생기게 된다.

이를 방지하기 위해 인터페이스 분리원칙(ISP)에서는 사용하지 않는 메서드가 있는 클래스에 의존하지 말라고 했다면,

CRP는 사용하지 않는 클래스를 가진 컴포넌트에 의존하지 말것을 상기시킨다.

 

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


응집도면에서 앞의 3가지 원칙들은 서로 상충하는 부분이 있다.

REP와 CCP는 컴포넌트의 크기를 크게 만들고, CRP는 컴포넌트를 작게 만든다.

REP는 릴리즈에 따라 컴포넌트의 크기가 커지게 되고

CCP는 단일 컴포넌트가 가지고 있는 책임에 대한 변경이 올 때 커지게 된다.

CRP는 컴포넌트내에 재사용 클래스의 수많은 의존성에 의해 내부의 응집도가 커지므로, 컴포넌트의 크기는 작아진다.

이러한 균형은 일반적으로 삼각형의 오른쪽에서 시작해서 왼쪽으로 이동한다.

(CCP와 CRP => REP와 CRP)

 

결론


어느 클래스들을 묶어서 컴포넌트를 만들지 결정할 때, 재사용성과 개발가능성이라는 상충하는 힘을 반드시 고려해야 한다.

위의 컴포넌트 응집도를 위한 원칙의 균형점은 거의 항상 유동적이므로 아키텍처가 애플리케이션의 요구에 맞게 균형을 잡아야 한다.