SOLID 설계 원칙은 응집도와 결합도를 기반으로 한다.
설계의 기본 원칙
응집도는 높게, 결합도는 낮게
응집도는 개별 모듈의 설계 원칙으로, 관련 있는 코드들로만 구성하도록 해야 한다. 결합도는 모듈(함수) 간의 관계에 해당한다.
- 응집도 -> 각각의 모듈을 어떻게 설계할 것인지
- 결합도 -> 모듈과 모듈 사이의 관계를 어떻게 설계할 것인지
1. Cohesion(응집도)
- 응집도는 한 모듈 안에서 코드의 기능적인 관련성의 강도를 의미
- 특정 기능 하나만을 수행하는 코드를 한 모듈 안에 두었을 때 가장 높은 응집도를 가짐
- 한 기능을 수행하는 모듈의 응집도 > 여러 기능을 수행하는 모듈의 응집도
1.1 응집도의 종류
- 기능적 응집도는 기능 하나만을 수행하는 모듈을 구성하고, 기능적 응집도를 제외한 나머지 응집도는 여러 기능을 수행하는 코드들이 한 모듈을 구성함
- 가능한 한 기능적 응집도, 순차적 응집도, 통신적 응집도 3가지를 충족하도록 하는 것이 좋음
- 특정 코드를 제거했을 때, 한 모듈에 얼마만큼 영향을 받는지(서로 관련이 있는지)에 따라 응집도를 결정
ex) 기능적 응집도를 갖는 모듈은 모듈의 어떤 코드 부분을 제거하면 기능을 제대로 수행하지 못함
1. 기능적 응집도(Functional cohesion)
- 실행에 관여하는 모든 것이 오직 하나의 문제만을 다룸
- 기능 하나만을 수행하도록 서로 연관되어 있기 때문에 어느 한 부분을 제거하면 이 모듈의 기능이 수행될 수 없음
- 기능적 응집도를 가진 모듈은 유지 보수에 용이하고, 이해하기 쉬움
- "Black box" : 내부가 어떤 식으로 구현되어 있는지 몰라도 기능 사용 가능
2. 순차적 응집도(Sequential cohesion)
- 순차적으로 데이터가 맞물려 있음
- 쉽게 재사용할 수 없는 문제점
기능적 응집도로 변환 -> 모듈을 쪼개면 각각의 모듈들을 재사용할 수 있음
3. 통신적 응집도(Communicaional cohesion)
- 동일한 입력 데이터를 사용함
ex) 두개의 정보를 필요로 하는 경우, 같이 묶어 하나의 모듈을 사용
- 서로 완전 관련이 없지는 않으나 순차적으로 관련있는 건 아님
- 독립적으로 사용 가능, 기능적으로 관련도 있음
- 쉽게 재사용할 수 없는 문제점 -> 개별적인 모듈로 분리시켜 각각의 상황에 맞게 사용
4. 절차적 응집도(Procedural cohesion)
- 다른 기능들을 가진 모듈이지만 실행 순서로 연결되어 있음(데이터와 관련 x)
- 한 모듈이 여러 개의 기능 사용
- 여러 기능의 실행 결과가 각각에 영향을 주지 않고 독립적으로 실행하지만 실행 순서로 묶여 있음
- 응집도를 높이기 위해서는 모듈을 분리시켜 사용하는 게 좋음
5. 시간적 응집도(Temporal cohesion)
- 기능적으로는 밀접한 관련이 없어도 한 모듈 안에서 특정 시점에 같이 실행
- 기능을 분리시키면 원하는 기능만 구현 가능
6. 논리적 응집도(Logical cohesion)
- 논리적으로 서로 유사성이 있어 한 모듈 안에 넣음
- 내부 구현을 알아야 실행 가능
- 플래그 변수를 하나만 선택해 기능을 수행
- 한 모듈 안에 있는 기능을 따로 분리시켜 사용하여 플래그 값에 따라 수행하는 기능이 달라지는 것을 해결할 수 있음
7. 우연적 응집도(Coincidental cohesion)
- 기능들이 서로 관련이 없는 코드들이 한 모듈 안에 구성되어 있음
- 피해야하는 설계
2. Coupling(결합도)
- 필요한 정보만 주고 받도록 호출 관계를 설정
- 가능한 독립적으로 모듈을 구성하도록 하여 결합도를 최소화해야 함
2.1 결합도의 종류
Normal 결합도에 데이터 결합도, 스탬프 결합도, 제어 결합도가 있고 좋은 결합에 속하고, 공통 결합도, 내용 결합도는 나쁜 결합도로 볼 수 있다.
1. Normal
인자를 주고 받으며 호출하는 관계(함수 호출을 통한 모듈 간의 결합)
1.1 데이터 결합도(Data Coupling)
- 파라미터(인자)로 소통
- 구조체로 인자 전달하면 안됨(-> Stamp coupling)
- 기본적인 데이터로만 인자 전달
- 인터페이스를 작게 유지
- 모든 데이터 요소는 필수적이라고 확신
- 모듈의 변경이 다른 모듈에게 영향을 주지 않음
1.2 스탬프 결합도(Stamp Coupling)
- 구조체가 존재(기본 자료형이 아니고 복합 자료형일 때)
- 구조체 일부분의 데이터만 필요한데, 구조체 형태로 데이터가 전달이 되어 data coupling보다 결합도가 있다.
- 전혀 상관 없는 데이터 필드의 변경이 일어나면 레코드를 사용하는 모듈에서 목적코드를 새로 만들어야 함
- 결합도를 낮추기 위해서 data 결합도의 방식으로 모듈에서 필요로 하는 정보만 주면 됨
1.3 제어 결합도(Control Coupling)
- 내부 로직을 결정하는 인자가 전달이 되면 둘 사이는 control 결합이 되었다고 봄
- 실제 데이터 처리가 이루어지는 data flag, 로직을 제어하는 control flag(ex. if 문)가 전달
- 대부분의 논리적 응집도를 가지는 모듈들은 다른 모듈들과 결합할 때 제어 결합도를 가짐
- same category를 가진 기능들을 내부 로직을 알기 위해 모듈을 나누는 게 좋음
2. 공통 결합도(Common Coupling)
- 전역 변수 사용 -> 공통 결합도가 생김, 가능한 한 생성하면 안됨
- 값 설정 시, 문제가 발생하면 데이터를 접근하는 모든 모듈을 검사해야 되므로 좋지 않은 결합
3. 내용 결합도(Content Coupling)
- 가장 나쁜 결합, 가장 강하게 결합되어 있음
- Java와 같은 고급 언어에서는 찾기가 힘든 결합이고, 어셈 블리어와 같은 저급 언어에서 발생할 수 있음
- 모듈의 변경이 결합되어 있는 다른 모듈에게 영향을 줌