성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

도구, 기술, 이론/이론

[클린 아키텍처] 컴포넌트 응집도와 세 가지 원칙

제이콥(JACOB) 2020. 2. 13. 15:26

 클린 아키텍처를 읽으며 정리 중이다. 봐도 봐도 좋은 책인 거 같다(까먹는 내가 문제지만...). 꼭 이 책에 의존적인 내용을 다루진 않겠지만 기초는 클린 아키텍처에 두고 있다고 알고 보면 좋을 거 같다.

 

  • REP: 재사용/릴리스 등가 원칙(Reuse/Release Equivalence Principle)
  • CCP: 공통 폐쇄 원칙(Common Closure Principle)
  • CRP: 공통 재사용 원칙(Common Reuse Principle)

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

재사용 단위는 릴리스 단위이다. 효과적인 재사용을 위해서는 변경 제어 시스템에서 릴리스를 추적해야 한다. 패키지는 효과적인 재사용 및 해제 단위이다.

 소프트웨어 컴포넌트가 릴리스 절차를 통해 추적 관리되지 않거나 릴리스 번호가 부여되지 않는다면 해당 컴포넌트를 재사용하고 싶어도 할 수 없고, 하지도 않을 것이다. 왜냐하면, 릴리스 번호가 없다면 재사용 컴포넌트들이 서로 호환되는지 보증할 방법이 없기 때문이다. 또한 개발자들이 새로운 릴리스 버전에 관해 어떤 것이 변했는지, 다음 버전에서는 어떤 것이 변할 것인지 알아야 하지만 알 수 없다.

 

 또한 만약 단순하게 한 클래스에서 코드를 복사해서 사용한다면, 원래 코드 작성자가 코드의 버그를 수정하거나 기능을 추가한 혜택을 자동으로 얻지 못한다. 개발자가 모두 수동으로 해야하는 일이 벌어진다.  

 

 이 원칙을 소프트웨어 설계와 아키텍처 관점에서 보면 단일 컴포넌트는 응집성 높은 클래스와 모듈로 구성되어야 함을 뜻한다. 단순히 임으로 선택된 클래스와 모듈로 구성되어서는 안되며, 모든 모듈은 서로 공유하는 중요한 테마나 목적이 있어야 한다. 그리고 하나의 컴포넌트로 묶인 클래스와 모듈은 버전 번호가 같아야 하며, 동일한 릴리스로 추적 관리되고, 동일한 릴리스 문서에 포함되어야 한다.

 

CCP: 공통 폐쇄 원칙

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

 이 원칙은 단일 책임 원칙(SRP)을 컴포넌트 관점에서 다시 쓴 것이다. 단일 컴포넌트는 변경의 이유가 여러 개 있어서는 안 된다는 것이다. 대다수의 애플리케이션에서 유지보수성(maintainability)은 재사용성보다 훨씬 중요하다. 애플리케이션에서 코드가 반드시 변경되어야 한다면, 이러한 변경이 여러 컴포넌트 도처에 분산되어 발생하기보다는, 차라리 변경 모두가 단일 컴포넌트에서 발생하는 편이 낫다.

 

 만약 변경을 단일 컴포넌트로 제한할 수 있다면, 해당 컴포넌트만 재배포하면 된다. 변경된 컴포넌트에 의존하지 않은 다른 컴포넌트는 다시 검증하거나 배포할 필요가 없다. 

 

 이 원칙은 개방 폐쇄 원칙(OCP)과도 밀접하게 관련되어 있다. OCP에서는 클래스가 변경에는 닫혀 있고 확장에는 열려 있어야 한다고 말한다. 100% 완전한 폐쇄란 불가능하므로 전략적으로 폐쇄해야 한다. 우리는 발생할 가능성이 있거나 과거에 발생했던 대다수의 공통적인 변경에 대해서 클래스가 닫혀 있도록 설계한다.

 

 따라서 변경이 필요한 요구사항이 발생했을 때, 그 변경이 영향을 주는 컴포넌트들이 최소한으로 한정될 가능성이 높아진다. 

 

SRP와의 유사성

CCP는 컴포넌트 수준의 SRP다. SRP에서는 서로 다른 이유로 변경되는 메서드를 서로 다른 클래스로 분리하라고 말한다. CCP에서는 서로 다른 이유로 변경되는 클래스를 서로 다른 컴포넌트로 분리하라고 말한다.

 

CRP: 공통 재사용 원칙

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

 CRP도 클래스와 모듈을 어느 컴포넌트에 위치시킬지 결정할때 도움되는 원칙이다. CRP에서는 같이 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함해야 한다고 말한다. 

 

 그런데 CRP는 어떤 클래스를 한데 묶어도 되는지보다는, 어떤 클래스를 한데 묶어서는 안 되는지에 대해서 훨씬 더 많은 것을 이야기한다. CRP는 강하게 결합되지 않은 클래스들을 동일한 컴포넌트에 위치시켜서는 안 된다고 말한다. 

 

ISP와의 관계

필요하지 않는 것에 의존하지 말라.

CRP는 ISP의 포괄적인 버전이다. ISP는 사용하지 않는 메서드가 있는 클래스에 의존하지 말라고 조언한다. CRP는 사용하지 않는 클래스를 가진 컴포넌트에 의존하지 말라고 조언한다.

 

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

 위의 세 원칙은 사실 서로 상충된다. REP와 CCP는 포함(inclusive) 원칙이며, 이 두 원칙은 컴포넌트를 더 크게 만든다. 반면 CRP는 배제(exclusive) 원칙이며, 컴포넌트를 더욱 작게 만든다. 뛰어난 아키텍트라면 이 원칙들이 균형을 이루는 방법을 찾아야 한다. 

 균형점을 찾더라도 시간이 흐름에 따라 프로젝트의 초점이 바뀌고, 그에 따라 컴포넌트를 구성하는 방식도 바뀌고 진화한다. 이들 사이에서 요구에 맞게 균형을 잡는 것이 중요하다.

반응형