[Clean Architecture] 컴포넌트 원칙(REP, CCP, CRP)
카테고리: Clean Architecture
컴포넌트
SOLID 원칙이 벽과 방에 벽돌을 배치하는 방법을 알려준다면, 컴포넌트 원칙은 빌딩에 방을 배치하는 방법을 설명해줍니다. 즉, 컴포넌트 원칙은 SOLID 원칙이 기반이 되어 큰 덩어리를 만드는 원칙이라고 보면 될것 같습니다.
이 책에서 말하는 컴포넌트란 배포가 가능한 가장 작은 단위 입니다. 자바의 경우 .jar파일이 컴포넌트 입니다. 루비에서는 .gem, 그리고 제가 많이 사용하는 닷넷 에서는 .dll 입니다. 즉, 닷넷에 익숙하다면 컴포넌트는 클래스 라이브러리라고 생각하시면 됩니다.
지금은 라이브러리를 개발하는 분들도 워낙 많고, 개인도 자신만의 라이브러리를 만들어 사용하는 시대입니다. 누구나 재사용 가능한 컴포넌트를 만드는 지금까지 약 50년의 세월이 필요했다고 합니다.
컴포넌트 응집도
어떤 클래스를 어느 컴포넌트에 포함시켜야 할까요? 이는 중요한 결정이므로 제대로 된 소프트웨어 엔지니어링 원칙의 도움을 받아야 합니다. 이 역시 원칙 없이 코딩 했다가는 나중에 유지보수가 불기능한 지경에 이를 수 있기 때문입니다. 책에서는 다음의 3가지 원칙을 제시합니다.
- REP(Reuse/Release Equivalence Principle) : 재사용/릴리스 등가 원칙
- CCP(Common Closure Principle) : 공통 폐쇄 원칙
- CRP(Common Reuse Principle) : 공통 재사용 원칙
REP : 재사용/릴리스 등가 원칙
재사용 단위는 릴리스 단위와 같다.
저자는 우리는 지금 소프트웨어 재사용의 시대에 살고 있고, 객체 지향 모델의 오랜 약속 중 하나가 실현되었다고 합니다. 그리고 어떻게 보면, 재사용/릴리스 등가원칙은 너무 당연해 보입니다. 소프트웨어 컴포넌트가 릴리스 절차를 통해 추적/관리 되지 않거나 릴리스 번호가 부여되지 않는다면 해당 컴포넌트를 재사용하고 싶어도 할 수도 없고, 하지도 않을 것이기 때문입니다.
따라서 이 원칙을 소프트웨어 설계와 아키텍처 관점에서 보면 단일 컴포넌트는 응집성이 높은 클래스와 모듈들로 구성되어야 함을 뜻합니다. 단순히 뒤죽박죽 임의로 선택된 클래스와 모듈로 구성되어서는 안됩니다. 컴포넌트를 구성하는 모든 모듈을 서로 공유하는 중요한 테마나 목적이 있어야 합니다.
이 원칙 만으로는 클래스와 모듈을 단일 컴포넌트로 묶는 방법을 제대로 설명하지 못하지만 이 원칙 자체는 중요합니다. 이 원칙을 어기는건 쉽게 발견할 수 있으며, 이 원칙의 약점은 다음 두 원칙 (CCP 와 CRP)으로 보완할 수 있습니다.
REP 는 재사용성과 관련된 원칙이므로, 프로젝트 초기에는 등한시될 가능성이 높습니다. 당연하게도 프로젝트 초기에는 당장 개발이 급급하기 때문입니다.
CCP : 공통 폐쇄 원칙
동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라, 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 분리하라.
이 원칙을 보면, SOLID 원칙의 SRP 와 비슷한점이 많고, CCP 자체가 SRP 를 컴포넌트 관점에서 기술한것 이라고 합니다.
SRP 에서 단일 클래스는 변경의 이유가 여러개 있어서는 안 된다고 말하듯이, 공통 폐쇄 원칙에서도 마찬가지 입니다. 단일 컴포넌트는 변경의 이유가 여러개 있어서는 안된다고 말합니다.
대다수의 애플리케이션에서 유지보수성은 재사용성보다 훨씬 중요합니다. 애플리케이션에서 코드가 반드시 변경되어야 한다면, 이러한 변경이 여러 컴포넌트 도처에 분산되어 발생하기 보다는 차라리 변경 모두가 단일 컴포넌트에서 발생하는 편이 낫습니다. 만약 변경을 단일 컴포넌트로 제한할 수 있다면, 해당 컴포넌트만 재배포 하면 됩니다. 변경된 컴포넌트에 의존하지 않는 다른 컴포넌트는 다시 검증하거나 배포할 필요가 없습니다.
CCP 는 같은 이유로 변경될 가능성이 있는 클래스는 모두 한곳으로 묶을 것을 권합니다. 물리적 또는 개념적으로 강하게 결합되어 항상 함께 변경되는 클래스들은 하나의 컴포넌트에 속해야 합니다. 이를 통해 소프트웨어를 릴리스, 재검증, 배포하는 일과 관련된 작업량을 최소화할 수 있습니다.
CCP 의 인사이트는 재사용성보다 유지보수성을 챙겨라 라고 보면 될 것 같습니다.
CRP : 공통 재사용 원칙
컴포넌트 사용자들을 필요하지 않는 것에 의존하게 강요하지 말라.
CRP 는 CCP 와 마찬가지로 컴포넌트를 어떻게 배치할 것인가? 에 관한 내용입니다. CCP 의 마지막 부분에서 CCP는 재사용성보다 유지보수성을 챙긴다 라고 했다면, CRP 는 반대로 유지보수성 보다는 재사용성을 챙겨라 입니다.
CRP 에서는 같이 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함해야 한다고 말합니다. 대체로 재사용 가능한 클래스는 재사용 모듈의 일부로서 해당 모듈의 다른 클래스와 상호작용하는 경우가 많습니다. CRP 에서는 이런 클래스들이 동일한 컴포넌트에 포함되어야 한다고 말합니다.
즉, 어떤 컴포넌트를 굴리기 위해서 재사용 되는 컴포넌트(계산을 하는 로직이 담긴 클래스라면 MathF 클래스)는 따로 분리하여 사용해야 한다고 합니다.
하지만 이 원칙을 보면, CCP 와는 반대의 성격을 띄고 있습니다. CCP 는 변경이되는 컴포넌트를 한데 모아라 였지만, CRP 를 적용하면 여러 컴포넌트로 분리가 되기 때문입니다.
CRP는 컴포넌트를 재사용 가능한 컴포넌트에 의존하게 만듭니다. 이러한 의존성으로 인해 사용되는 컴포넌트가 변경될 때마다 사용하는 컴포넌트도 변경해야 할 가능성이 높습니다. 또는 사용하는 컴포넌트를 변경하지 않더라도, 재컴파일, 재검증, 재배포를 해야 하는 가능성은 여전히 남아 있습니다. 심지어 사용되는 컴포넌트에서 발생한 변경이 사용하는 컴포넌트와는 전혀 관련 없는 경우에도 유요합니다.
따라서 의존하는 컴포넌트가 있다면 해당 컴포는트의 모든 클래스에 대해 의존함을 확실히 인지해야 합니다. 그렇지 않으면 필요 이상으로 많은 컴포넌트를 재배포하느라 우리의 소중한 노력을 허비하게 됩니다.
따라서 CRP는 어떤 클래스를 한데 묶어도 되는지보다는 어떤 클래스를 한데 묶어서 안되는지를 더 생각하게 하는 원칙입니다. CRP는 강하게 결합되지 않은 클래스들을 동일한 컴포넌트에 위치시켜서는 안된다고 말합니다.
댓글 남기기