9-2 모듈화 설계(결합력의 이해)

윤효준·2025년 7월 21일
0

소프트웨어 공학

목록 보기
17/43

🔗 결합력(Coupling)

결합력이란 모듈 간의 의존성 강도를 의미합니다.
결합력이 낮을수록(loose coupling) 모듈이 독립적으로 동작할 수 있어 유지보수, 확장성, 재사용성 측면에서 유리합니다.

좋은 설계를 위해서는 모듈이 독립적인 기능을 갖도록 하고, 불필요한 중복이나 상호참조를 피하는 것이 중요합니다.


✅ 낮은 결합력의 장점

  • 시스템 구성 요소 간 의존성이 느슨해짐
  • 변경에 의한 파급(파동) 효과를 최소화함
  • 소프트웨어의 이해도와 예측 가능성이 높아짐
  • 모듈 인터페이스가 단순해져 테스트 및 유지보수 용이

💬 파동 효과란?
한 모듈의 변경이 다른 모듈에 연쇄적으로 영향을 주는 현상입니다.
예: A 모듈의 내부 구현을 바꿨더니 B, C, D 모듈까지 수정이 필요해지는 상황.


📊 결합력의 종류 (강도 순)

결합력은 아래와 같이 느슨한 결합 → 강한 결합으로 나눌 수 있습니다:

메시지 결합 < 데이터 결합 < 스탬프 결합 < 제어 결합 < 외부 결합 < 공유 결합 < 내용 결합

모듈 간의 결합력 정도를 표현하는 유형 및 스케일


🟢 메시지 결합 (Message Coupling) – 가장 느슨한 결합

모듈 간 상호작용이 메시지 전달(메서드 호출 또는 이벤트)에 의해 이루어지는 경우입니다.
상태 공유 없이, 인터페이스만을 통해 통신하는 것이 특징입니다.

💬 예시

  • iframe 간 통신: window.postMessage()로 메시지를 주고받음
  • Microservice: REST API 호출, 메시지 큐 사용

🟢 데이터 결합 (Data Coupling)

모듈 간 기본 자료형(primitive type) 형태의 데이터를 주고받는 방식입니다.
전달되는 데이터가 명확하며, 독립성이 비교적 높습니다.

💬 예시

  • calculateTax(price, quantity) – 기본 타입 전달
  • addUser(name, age) – 불필요한 정보 없이 명시적으로 필요한 데이터만 전달

🟡 스탬프 결합 (Stamp Coupling)

구조체(struct), 객체(object) 등 복합 자료형을 통째로 주고받는 방식입니다.
불필요한 데이터까지 전달되거나, 구조 변경 시 파급효과가 발생할 수 있습니다.

💬 예시

  • processOrder(Order order) – 내부에서 Order 객체의 일부 필드만 사용
  • DTO에 포함된 불필요한 필드가 많아 구조 변경 시 영향 받음

🟠 제어 결합 (Control Coupling)

모듈이 flag(제어 변수)를 전달하여 상대 모듈의 내부 동작을 결정하는 경우입니다.
호출하는 쪽에서 논리를 제어하므로 높은 의존성을 가지게 됩니다.

💬 예시

  • renderPage(boolean isAdmin) – 내부 로직이 if (isAdmin)에 따라 달라짐
  • 제어 플래그 값 하나로 동작이 바뀌는 함수

🔴 외부 결합 (External Coupling)

외부 시스템 또는 리소스(파일, 디바이스, DB 등)를 통해 간접적으로 연결된 경우입니다.
모듈 간 간접적이지만 공유된 외부 자원에 의해 영향을 받습니다.

💬 예시

  • 여러 모듈이 같은 설정 파일, DB 테이블, 하드웨어 디바이스를 공유
  • 로그 파일에 동시에 접근하는 Logger

🔴 공유 결합 (Common Coupling)

여러 모듈이 전역 변수(global variable)를 공유할 때 발생합니다.
간단해 보일 수 있지만, 모듈 간 의존성이 매우 커지며 디버깅과 테스트가 어려워집니다.

💬 예시

  • public static GlobalConfig config; – 전역 객체를 여러 클래스가 직접 참조
  • 전역 변수 currentUser를 모든 모듈이 사용

🔴 내용 결합 (Content Coupling) – 가장 강한 결합

한 모듈이 다른 모듈의 내부 구현(코드, 변수 등)을 직접 참조하는 경우입니다.
정보 은닉 원칙을 완전히 위배하며, 현대적 설계에서는 거의 사용되지 않습니다.

💬 예시

  • moduleB.variableA = 10; – moduleB가 moduleA 내부 변수에 직접 접근
  • goto moduleB.labelX; – 코드 흐름이 외부 모듈 내부로 직접 진입

✅ 결론

  • 느슨한 결합은 유지보수성, 확장성, 재사용성, 안정성 측면에서 필수입니다.
  • 결합력은 되도록 메시지 결합이나 데이터 결합 수준에서 유지하는 것이 이상적입니다.
  • 지나치게 강한 결합(공유/내용 결합)은 리팩토링 우선 대상입니다.
profile
작은 문제를 하나하나 해결하며, 누군가의 하루에 선물이 되는 코드를 작성해 갑니다.

0개의 댓글