컴포넌트 - 응집도(REP, CCP, CRP) S/W 설계

- 이 글은 로버트 C.마틴의 Clean Architecture를 기반으로 작성되었습니다. (가능하면 책을 읽어보는것을 추천한다.)
- https://adriancitu.com/tag/the-reuse-release-equivalence-principle/

- 개요
우리는 프로그램을 개발할 때 어떤 클래스를 어떤 컴포넌트에 포함시킬것이가에 대해 진지하게 생각해보지 않는다. 
사실은 엔지니어링 원칙을 고려해보면서 생각해보아야 하지만 몰라서 고려하지 않을 수도 있고, 귀찮아서 하지 않을 수도 있다. 컴포넌트 응집도에는 아래와 같이 세 가지의 원칙이 있다.
  • REP: 재사용/릴리스 등가 원칙
  • CCP: 공통 폐쇄 원칙
  • CRP: 공통 재사용 원칙

- REP: 재사용/릴리즈 등가 원칙
재사용 단위는 릴리스 단위와 같다.
소프트웨어 컴포넌트가 릴리스를 통해 추적 관리 되지 않거나, 릴리즈 번호가 없다면 사용하는 입장에서 혼돈에 빠질것이다. 우리는 버전명과 릴리스 노트를 보고 해당 컴포넌트를 신규버전으로 업데이트 할지 그대로 사용할지를 결정한다.
아키텍처 관점에서 이 원칙을 생각해보면 단일 컴포넌트는 응집성 높은 클래스와 모듈들로 구성되어야 함을 의미한다. 클래스들을 아무거나 선택해서 컴포넌트로 묶으면 안된다는 뜻이다.
이 원칙은 너무도 당연해서 어기면 안된다는 늬앙스가 강하다. 하지만 이 원칙자체는 아키텍처 설계에 있어서 중요하다.

- CCP: 공통 폐쇄 원칙
동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라. 
어디서 많이 들어본말이지 않은가? SOLID 원칙중 SRP 원칙을 컴포넌트 레벨에서 적용한것이다.
대다수 어플리케이션에서 유지보수는 매우 중요하다. 어떤 요구사항이나 이유로 코드를 변경할 때, 여러 컴포넌트를 모두 변경하는것이 아니라 단일 컴포넌트만 변경할 수 있도록 설계 했다면 훌륭한 설계라 할 수 있다.
배포 측면에서도 해당 컴포넌트만 배포하면 되기 때문에 작업이 훨씬 수월하다. 테스트를 할 때에도 여러 컴포넌트가 수정되면 해당 컴포넌트들은 모두 테스트를 다시 해야 한다.
CCP는 컴포넌트 수준에서의 SRP이다. SRP에서는 클래스는 다른 이유로 변경되는(다른 액터에 의해서 변경되는) 메소드를 클래스로 추출, 분리하라고 말한다. CCP 에서는 서로 다른 이유로 변경되는 클래스들을 다른 컴포넌트로 분리하라고 말하고 있다.
동일 시점 및 동일 이유로 변경되는 것들을 한데로 묶고, 다른 시점 및 다른 이유로 변경되는 것들을 분리하라.

- CRP: 공통 재사용 원칙
컴포넌트 사용자들을 필요하지 않은 것에 의존하게 하지 마라.
CCP와 SRP의 유사성처럼 SOLID를 조금이나마 기억하고 있다면 위 문구를 보고 ISP 원칙을 떠올릴 수 있어야 할것이다. 앞서 SOLID-ISP 원칙 에서 사용자들이 필요하지 않은 행위에 의존하지 않게 하기 위해 각 사용자별로 인터페이스를 만들고, 각 사용자들이 필요한 행위의 메소드들만 인터페이스에 정의하여 분리하였다. CRP는 ISP의 컴포넌트 레벨의 버전인셈이다.
CRP 에서는 재사용되는 경향이 있는 클래스와 모듈을 같은 컴포넌트로 배치해야 한다고 말한다. 예를 들어 컨테이너 클래스와 클래스의 이터레이터는 서로 강결합이라 함께 재사용된다. 따라서 이들 클래스는 동일 컴포넌트에 위치해야 한다.
필요하지 않은 것에 의존하지 말라.

- 컴포넌트 응집도 다이어그램
REP와 CCP는 포함원칙이며, CRP는 배제원칙이다. 이들 세 원칙은 서로 상충된다. 아래 그림은 응집도와 관련한 원칙에서 유명한 다이어그램이다. 각 변은 맞은편 정점을 포기했을 때 치뤄야 하는 댓가를 나타내고 있다.
REP와 CRP에만 중점을 두면 사소한 변경시에 너무 많은 컴포넌트에 영향(그림에서 Too many components change)을 미친다.
CCP와 REP에만 중점을 두면 릴리스(그림에서 Too many unneeded releases)가 너무 빈번해진다.
프로젝트 초기에는 재사용성 보다는 생산성이 중요하다. 위의 그림에서 오른쪽(CCP)에 중점적인 가치를 둔다. 프로젝트가 완료되어 유지보수하거나 해당 프로젝트로 부터 고도화나 또 다른 프로젝트가 파생되면 왼쪽(REP)이 중요해진다. 

- 결론
어떤 클래스들을 묶어서 컴포넌트로 만들 때 재사용성과 개발성이라는 상충하는 힘을 고려해야한다. 또한 지금 내가 중점적으로 두고 있는 가치가 시간이 흐름에 따라 변할 수도 있다는 사실을 명심하고 균형을 맞추도록 노력해야한다.

덧글

댓글 입력 영역