응집도와 결합도
모듈은 높은 응집도와 낮은 결합도를 가진 구조로 설계하는 것이 좋다.
일반적으로 좋은 설계는 모듈의 독립성을 최대한 보장하는 설계인데 모듈의 독립성은 응집도와 결합도로 측정한다.
독립성이 높은 모듈일수록 서로에게 영향을 거의 끼치지 않으며 오류가 발생해도 쉽게 수정 가능하다.
모듈의 독립성은 결합도를 약하게, 응집도를 강하게 모듈의 크기가 작을 때 높아진다.
#결합도
결합도는 모듈간의 상호 의존하는 정도 또는 두 모듈 간의 연관관계를 말한다.
결합도가 낮을수록 모듈간의 독립성은 높아진다.
1. 자료 결합 (Data Coupling)
- 모듈 간에 파라미터 만으로 데이터를 주고받는 결합
- 가장 결합도가 낮고 좋은 형태이다.
여기서 주고받는 데이터는 기능 수행에 있어 로직을 제어하거나 하지 않는 순수한 자료형 요소이다.
또한 한 모듈을 변경하더라도 다른 모듈에는 영향이 미치지 않는 결합 상태이다.
public void foo() {
int result = add(5,3);
}
public int add(int a, int b) {
return a+b;
}
2. 스탬프 결합 (Stamp Coupling)
- 두 모듈이 동일한 자료 구조를 참조하는 형태의 결합도
- 모듈 간에 인터페이스로 배열 또는 오브젝트 등이 전달되는 경우를 말한다.
자료 구조의 형태가 변경되면 그것을 참조하는 모든 모듈에 영향을 주며 변경되는 필드를 참조하지 않는 모듈에서도 영향을 받을 수 있다.
예시에서 클래스의 필드가 변경되는 경우 이를 참조하는 모듈에서도 변경이 필요할 수 있다.
public void foo() {
Product p = new Product("아이폰 13", 1300000);
addToCart(p);
}
public void addToCart(Product p) {
// 장바구니 상품 추가 로직
}
3. 제어 결합 (Control Coupling)
- 어떤 모듈이 다른 모듈 내부의 논리적 흐름을 제어하는 파라미터를 전달하는 경우
- 파라미터로 전달되는 값에 따라서 모듈 내부 로직의 처리가 달라지는 Flag 값 등으로 결합되는 형태
public void foo() {
printReport(true);
}
public void printReport(boolean isManager) {
if (isManager) {
printManagerReport();
} else {
printUserReport();
}
}
4. 외부 결합 (External Coupling)
- 모듈이 외부에 있는 다른 모듈 또는 데이터를 참조할 때의 결합 형태
- 외부 결합도는 모듈이 외부의 데이터, 통신 프로토콜 등을 공유할 때 발생
데이터를 참조 또는 공유하는 결합형태가 공통 결합과 비슷하지만 차이점으로 참조하는 데이터가 외부에 위치한다는 점이 있다.
5. 공통 결합 (Common Coupling)
- 여러 모듈이 하나의 데이터 영역을 참조하여 사용하는 형태
- 전역 변수 사용을 예로 들 수 있다. (자바의 경우 클래스 변수, 인스턴스 변수)
전역 변수의 변경이 여러 모듈에 영향을 미칠 수 있다.
6. 내용 결합 (Content Coupling)
- 한 모듈이 다른 모듈의 내부 기능과 데이터를 직접 참조하는 경우
- 가장 높은 결합도를 가지므로 좋지 않은 형태이다
사용하고자 하는 모듈의 코드를 알고있어야하고, 모듈의 변경이 발생한 경우 참조하는 모듈들 모두 코드의 변경이 필요하므로 가장 좋지 않은 결합이다.
#응집도
응집도는 모듈의 내부 요소들이 서로 얼마나 관련있는지에 대한 척도이며, 응집도가 높을수록 모듈의 독립성이 높다고 할 수 있다.
1. 기능적 응집도 (Functional Cohesion)
- 모듈내 모든 요소들이 하나의 기능을 수행하기 위해 구성된 경우.
- 가장 응집도가 높으며 가장 좋은 결합 형태이다.
예를 들어 회원관리 기능을 모아놓은 클래스이다.
2. 순차적 응집도 (Sequential Cohesion)
- 한 요소의 입력이 다른 요소의 입력으로 차례로 사용되는 형태
public void foo() {
String data = readData();
printData(data);
}
3. 통신적 응집도 (Communicational Cohesion)
- 동일한 입력과 출력을 사용하여, 다른 기능을 수행하는 활동들이 모여있는 경우
- 순차적 응집도와 다르게 처리 순서가 중요하지 않다.
4. 절차적 응집도 (Procedural Cohesion)
- 모듈내에서 여러 기능 요소가 순차적으로 수행되지만 다음 기능 요소로 데이터가 아닌 제어요소가 전달되는 경우
- 예를들어 제품 삭제를 할 때 권한을 확인한 후에 삭제를 진행하는 형태
5. 시간적 응집도 (Temporal Cohesion)
- 각 기능 요소들이 순서에 관계없이 특정 시간에 반드시 수행되는 것을 모아둔 경우
- 예를 들어 프로그램이 구동될 때 데이터 초기화나 객체 초기화 등을 진행하는 유형
6. 논리적 응집도 (Logical Cohesion)
- 유사한 성격을 갖거나 특정 형태로 분류되는 처리 요소들이 한 모듈에서 처리되는 경우
7. 우연적 응집도 (Coincidental Cohesion)
- 모듈 내부의 각 구성 요소들이 아무런 관련 없이 구성되어 있는 경우
- 논리적 응집도와 비슷하지만 유사한 성격이나 형태가 없어서 모듈 수정이 사이드 이펙트를 발생시킬 가능성이 높다.
- 가장 좋지 않은 응집도를 갖고 있다.
사이드 이펙트
- 함수나 표현식이 외부의 상태를 변경하거나 예상하지 못한 상황에서 문제가 생기는 현상