Skip to content

Latest commit

 

History

History
78 lines (40 loc) · 7.19 KB

File metadata and controls

78 lines (40 loc) · 7.19 KB

13장 컴포넌트 응집도

어떤 클래스를 어떤 컴포넌트에 포함시켜야 할까? 이는 중요한 결정이므로 제대로 된 스포트웨어 엔지니어링 원칙의 도움을 받아야한다. 이 장에서는 컴포넌트 응집도와 관련된 세 가지 원칙을 논의한다.

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

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

어찌보면 재사용/릴리스 등과 원칙은 너무 당연해 보인다. 소프트웨어 컴포넌트가 릴리스 절차를 통해 추적 관리되지 않거나 릴리스 번호가 부여되지 않는다면 해당 컴포넌트를 재사용하고 싶어도 할 수 없을 것이다.

하지만 이보다 중요한 이유는 새로운 버전이 언제 출시되고 무엇이 변했는지를 개발자들(해당 소프트웨어를 사용하는) 이 알아야하기 때문이다. 새로운 릴리스 소식을 접하면, 개발자는 변경 사항을 문서 혹은, 공지를 통해 확인하고 기존 버전을 유지할지, 새로운 릴리스를 통합할지 결정한다.

이 원칙을 아키텍처 관점에서 보면 단일 컴포넌트는 응집성 높은 클래스와 모듈들로 구성되어야 함을 뜻한다. 컴포넌트를 구성하는 모든 모듈들은 서로 공유하는 중요한 테마나 목적이 있어야 한다.

하나의 컴포넌트로 묶인 클래스와 모듈은 반드시 함께 릴리스할 수 있어야한다.

이 원칙은 다음에 다룰 두 원칙이 지닌 강점을 통해 충분히 보완할 수 있다. CCP와 CRP는 REP를 엄격하게 제약을 가하는 측면에서 정의한다.

CCP: 공통 폐쇄 원칙

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

이 원칙은 SRP 를 컴포넌트 관점에서 다시 쓴것이다. SRP에서 단일 클래스는 변경의 이유가 여러개 있으면 안 된다고 말하듯, CCP는 단일 컴포넌트는 변경의 이유가 여러개 있으면 안된다고 말한다.

대다수의 애플리케이션에서 유지보수성은 재사용성보다 훨씬 중요하다. 따라서 애플리케이션에서 코드가 반드시 변경되어야 한다면, 여러 곳에서 발생되는 것보다 단일 컴포넌트에서 변경 모두가 발생하는 것이 낫다. 만약 변경을 단일 컴포넌트로 제한할 수 있다면, 해당 컴포넌트만 재배포하면 된다.

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

이 원칙은 OCP(개방 폐쇄 원칙)과도 밀접하게 관련되어있다. CCP에서는 동일한 유형의 변경에 대해 닫혀있는 클래스들을 하나의 컴포넌트로 묶음으로써 OCP의 교훈을 확대 적용한다. 따라서, 변경이 불가피하게 발생한 경우, 그 변경이 영향을 주는 컴포넌트들이 최소한으로 한정될 가능성이 높아진다.

SRP와의 유사성

앞서 언급했듯, CCP는 컴포넌트 수준의 SRP이다. SRP는 서로 다른 이유로 변경되는 메서드를 서로 다른 클래스로 분리하라고 말한다. 두 원칙은 모두 다음과 같은 교훈으로 요약할 수 있다.

동일한 시점에 동일한 이유로 변경되는 것들을 한데 묶어라. 서로 다른 시점에 다른 이유로 변경되는 것들을 서로 분리하라.

CRP: 공통 재사용 원칙

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

이 원칙또한 클래스와 모듈을 어느 컴포넌트에 위치시킬지 결정할 때 도움되는 원칙이다.

개별 클래스가 단독으로 재사용되는 경우는 거의 없다. 대체로 재사용 가능한 클래스는 재사용 모듈의 일부로써 해당 모듈의 다른 클래스와 상호작용하는 경우가 많다. CRP는 이렇게 재사용되는 경향이 있는 클래스와 모듈들은 같은 컴포넌트에 포함해야 한다고 말한다.

그런데 이게 전부가 아니다. CRP는 컴포넌트에 어떤 클래스를 포함할지 설명하기도하지만, 어떤 클래스를 같이 묶으면 안될지 또한 말해준다.

A 컴포넌트B 컴포넌트를 사용하면, 두 컴포넌트 사이에는 의존성이 생겨난다. 이 같은 의존성으로 인해 사용되는 컴포넌트가 변경될 때마다 사용하는 컴포넌트도 변경해야 할 가능성이 높다. 또는 사용하는 컴포넌트를 변경하지 않더라도, 재검증, 재배포를 해야 하는 가능성은 여전히 남아있다.

따라서 의존하는 컴포넌트가 있다면 해당 컴포넌트의 모든 클래스에 대해 의존함을 확실히 인지해야한다. 즉, 일부 클래스에만 의존한다거나, 일부 클래스와는 독립적일 수 없음을 확실히 인지해야한다.

따라서 CRP는 어떤 클래스를 한데 묶어서 안되는지에 대해 더 말하고 있는 원칙이다. CRP는 강하게 결합되지 않는 클래스들은 동일한 컴포넌트에 위치시켜서는 안 된다고 말한다.

ISP와의 관계

CRP는 ISP(인터페이스 분리 원칙)의 포괄적인 버전이다. ISP는 사용하지 않는 메서드가 있는 클래스에 의존하지 말라고 조언한다. CRP는 사용하지 않는 클래스를 가진 컴포넌트에 의존하지 말라고 조언한다. 이 두 조언은 다음의 한 문장으로 요약할 수 있다.

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

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

앞서 살펴본 응집도에 관련된 세가지 원칙은 서로 상충된다.

  • REPCCP는 포함 원칙이다. 즉, 컴포넌트를 더 크게 만든다.
  • CRP는 배제 원칙이다. 즉, 컴포넌트를 더 작게 만든다.

아래 그림 13.1은 균형 다이어그램으로, 응집도에 관한 세 원칙이 상호작용하는 방식을 나타낸다.

cohesion-principles-tension-diagram

오로지 REP와 CRP에만 중점을 두면, 사소한 변경이 생겼을 때 너무 많은 컴포넌트에 영향을 미친다. 반대로 CCP와 REP에만 과도하게 집중하면 불필요한 릴리스가 너무 빈번해진다.

일반적으로 프로젝트는 삼각형의 오른쪽(CCP)에서 시작하는 편이며, 이때는 오직 재사용성만 희생하면 된다. 프로젝트가 진행되면, 점차 왼쪽(REP)로 이동해 간다. 다시말해 프로젝트가 실제로 수행하는 일 자체보다는 프로젝트가 발전되고 사용되는 방법과 더 관련이 깊다.

결론

응집도에 관한 세 가지 원칙은 응집도가 가질 수 잇는 훨씬 복잡한 다양성을 설명해 준다. 이들 사이에서 애플리케이션의 요구에 맞게 균형을 잡는 일은 중요하다.

심지어 이 균형점은 거의 항상 유동적이다. 즉, 두 힘을 현재 상황에 맞게 잘 분배했더라도, 내년이 되면 맞지 않을 수 있다. 결과적으로 시간이 흐름에 따라 프로젝트의 초점이 개발가능성에서 재사용성으로 바뀌고, 그에 따라 컴포넌트를 구성하는 방식도 조금씩 진화한다.