2025년 6월 21일 작성
결합도는 낮추고 응집도는 높이기
결합도를 낮추고 응집도를 높이는 것은 software 품질을 향상시키는 핵심 원칙입니다.
낮은 결합도 + 높은 응집도
- 소프트웨어 설계에서 결합도(Coupling)는 낮추고 응집도(Cohesion)는 높이는 것이 품질 좋은 system을 만드는 핵심 원칙입니다.
- 결합도는 module 간의 의존성과 상호작용의 정도를 나타내고, 응집도는 module 내부 요소들이 얼마나 밀접하게 관련되어 있는지를 나타냅니다.
- 낮은 결합도와 높은 응집도를 유지하면 code의 유지 보수성, 재사용성, 확장성이 크게 향상됩니다.
결합도 (Coupling)
- 결합도는 서로 다른 module이나 component 간의 의존성 정도를 측정하는 지표입니다.
- 결합도가 높다는 것은 module들이 서로 강하게 의존하고 있어서, 하나의 module을 변경할 때 다른 module들도 함께 수정해야 한다는 의미입니다.
- 반대로 결합도가 낮다는 것은 module들이 독립적으로 동작할 수 있어서, 한 module의 변경이 다른 module에 미치는 영향이 최소한이라는 의미입니다.
결합도가 낮은 설계의 좋은 점
- 독립적인 개발과 배포가 가능해집니다.
- 각 module을 별도의 team에서 독립적으로 개발할 수 있습니다.
- module별로 다른 배포 주기를 가질 수 있어서 개발 속도가 빨라집니다.
- 장애 격리가 쉬워집니다.
- 한 module에서 발생한 문제가 다른 module로 전파되지 않습니다.
- system의 전체 가용성이 향상됩니다.
- 기술 선택의 자유도가 높아집니다.
- 각 module에서 서로 다른 programming language나 framework를 사용할 수 있습니다.
- 요구 사항에 가장 적합한 기술을 module별로 선택할 수 있습니다.
- test 작성과 실행이 간단해집니다.
- mock이나 stub을 활용하여 격리된 환경에서 test할 수 있습니다.
- 병렬로 test를 실행할 수 있어서 전체 test 시간이 단축됩니다.
결합도가 높은 설계의 문제점
- 변경 시 파급 효과가 크기 때문에 code 수정이 어려워집니다.
- 하나의 module을 수정하면 관련된 여러 module을 동시에 수정해야 합니다.
- 예상하지 못한 곳에서 bug가 발생할 가능성이 높아집니다.
- testing이 복잡해지고 시간이 많이 소요됩니다.
- 의존 관계가 복잡하기 때문에 단위 test를 작성하기 어려워집니다.
- test를 위해 여러 module을 함께 준비해야 합니다.
- code 재사용이 어려워집니다.
- module을 다른 project에서 사용하려면 의존하는 모든 module을 함께 가져와야 합니다.
응집도 (Cohesion)
- 응집도는 하나의 module 내부에서 요소들이 얼마나 밀접하게 관련되어 있는지를 나타내는 지표입니다.
- 응집도가 높다는 것은 module 내의 모든 요소가 하나의 명확한 목적을 위해 협력하고 있다는 의미입니다.
- 응집도가 낮다는 것은 module 내에 서로 관련 없는 기능들이 섞여 있어서 module의 목적이 불분명하다는 의미입니다.
응집도가 높은 설계의 좋은 점
- 명확한 책임과 역할로 인해 code를 이해하기 쉬워집니다.
- module의 이름만 봐도 어떤 일을 하는지 직관적으로 알 수 있습니다.
- 새로운 개발자도 빠르게 code 구조를 파악할 수 있습니다.
- 변경의 영향 범위가 명확하고 제한적입니다.
- 특정 기능을 수정할 때 어느 module을 건드려야 하는지 쉽게 파악할 수 있습니다.
- 한 module 내에서 변경이 완료되어 side effect를 예측하기 쉽습니다.
- 재사용성과 모듈화가 극대화됩니다.
- 완전한 기능 단위로 module이 구성되어 있어서 다른 context에서도 그대로 사용할 수 있습니다.
- 불필요한 dependency 없이 필요한 기능만 선택적으로 사용할 수 있습니다.
- debugging과 maintenance가 효율적입니다.
- 문제가 발생했을 때 관련 module을 빠르게 찾을 수 있습니다.
- 기능별로 명확히 분리되어 있어서 성능 최적화나 refactoring이 안전합니다.
응집도가 낮은 설계의 문제점
- module의 역할과 책임이 불분명해집니다.
- 하나의 module이 여러 가지 서로 다른 일을 처리하게 됩니다.
- code를 읽고 이해하기 어려워집니다.
- 변경과 확장이 어려워집니다.
- 특정 기능만 수정하려고 해도 관련 없는 기능까지 영향을 받을 수 있습니다.
- 새로운 기능을 추가할 때 어느 module에 넣어야 할지 판단하기 어려워집니다.
- 재사용성이 떨어집니다.
- 필요한 기능만 사용하고 싶어도 불필요한 기능까지 함께 포함되어 있습니다.
낮은 결합도와 높은 응집도 = Software 품질 향상
- 결합도를 낮추고 응집도를 높이면, software의 품질이 크게 향상됩니다.
유지 보수성 향상
- 독립적인 module 구조로 인해 변경 사항의 파급 효과가 최소화됩니다.
- 특정 module의 내부 구현을 변경해도 다른 module에 영향을 주지 않습니다.
- bug 수정이나 기능 개선 시 수정 범위를 예측하고 제한할 수 있습니다.
- 명확한 책임 분리로 인해 문제 발생 시 원인을 빠르게 파악할 수 있습니다.
개발 효율성 증대
- 병렬 개발이 가능해집니다.
- 서로 다른 개발자가 독립적인 module을 동시에 개발할 수 있습니다.
- module 간 interface만 합의하면 각자 내부 구현에 집중할 수 있습니다.
- testing이 단순해집니다.
- 각 module을 독립적으로 test할 수 있어서 unit test 작성이 쉬워집니다.
- mock object를 활용한 격리된 test 환경 구성이 가능합니다.
재사용성과 확장성 확보
- module의 독립성 덕분에 다른 project에서도 쉽게 재사용할 수 있습니다.
- 새로운 기능 추가 시 기존 code에 미치는 영향을 최소화할 수 있습니다.
- 새로운 module을 추가하거나 기존 module을 교체하는 것이 안전해집니다.
Code 품질 향상
- 가독성이 좋아집니다.
- 각 module의 역할이 명확하기 때문에 code를 이해하기 쉬워집니다.
- 전체 system의 구조를 파악하기 쉬워집니다.
- 설계의 일관성이 유지됩니다.
- 명확한 책임 분리로 인해 architecture가 안정적으로 유지됩니다.
실무에서의 적용 방법
- 낮은 결합도와 높은 응집도를 실현하기 위해, 다양한 설계 원칙과 pattern을 적용할 수 있습니다.
Interface 활용
- 추상화된 interface를 통해 module 간 통신하여 결합도를 낮춥니다.
- 구체적인 구현체가 아닌 interface에 의존하도록 설계합니다.
- Dependency Injection pattern을 활용하여 의존성을 외부에서 주입받습니다.
단일 책임 원칙 준수
- 하나의 module은 하나의 책임만 가지도록 설계하여 응집도를 높입니다.
- class나 function이 변경되는 이유가 오직 하나여야 합니다.
- 서로 다른 이유로 변경되는 기능들은 별도의 module로 분리합니다.
정보 은닉 적용
- module 내부의 구현 세부 사항을 외부에서 직접 접근할 수 없도록 숨깁니다.
- public interface를 통해서만 module과 상호작용하도록 제한합니다.
- 내부 구현 변경 시 외부에 미치는 영향을 차단합니다.
계층화 구조 설계
- 관심사별로 계층을 분리하여 각 계층의 응집도를 높이고 계층 간 결합도를 낮춥니다.
- presentation layer, business logic layer, data access layer로 구분합니다.
- 상위 계층이 하위 계층에만 의존하도록 dependency 방향을 통제합니다.