출처
개인의 견해 및 추가 정리 내용이 포함되어 있습니다.
목차
모듈 (Module)
- 소프트웨어를 기능별로 구분한 리소스 단위이며, 이를 분류하는 과정을 모듈화(Modularization)라고 한다.
- 하나의 기능을 달성하기 위해 동작하며, 독립적으로 컴파일 가능한 모든 단위가 포함된다.
e.g. 프로그램, 클래스, 함수
모듈(화)의 장점
1. 단일 장애의 전파를 최소화 할 수 있다.
2. 장애 파악이 쉽고 픽스에도 용이하다.
3. 구조 파악이 쉽고, 기능별 단위 테스트에 용이하여 유지보수에 유리하다.
4. 재사용성이 높아 확장 및 유연한 프로그램 작성에 용이하다.
- 일반적으로, 모듈의 독립성이 높은 프로그램을 좋은 소프트웨어로 여긴다.
- 모듈의 독립성을 판단하는 척도로 결합도(Coupling)와 응집도(Cohesion)가 존재한다.
모듈의 독립성 - 실생활의 비유
- 완제품 자동차를 소프트웨어에 빗대면, 모듈은 각 기능을 담당하는 바퀴, 핸들, 좌석, 엔진 등이 있다.
(좌석을 운전자석, 조수석 등으로 더 상세히 모듈화 하는 것은 개발자의 몫이다.)
=> 모듈
- 좋은 자동차란, 바퀴의 성공적인 동작(기능)에 관한 내용은 바퀴에 집중되어야 한다.
=> 높은 응집도
- 바퀴는 독립적으로 동작하며 결함이 다른 모듈에 영향을 미치지 않는 것이 이상적이다. 하지만, 바퀴와 핸들과 같이 상호작용이 필연적일 수 있다. 그렇다고 바퀴의 교체를 위해 핸들까지 교체해야 한다면 이는 잘못된 설계(결합도가 매우 높은)이다.
=> 낮은 결합도
- 즉, 좋은 자동차란 바퀴의 기능에 관한 요소는 바퀴에 집중하며, 다른 모듈의 의존은 최소화 하는 것이다.
=> 좋은 소프트웨어란, 응집도가 높고 결합도가 낮은(high cohesion loose coupling) 모듈로 이루어져 있다.
=> 이는 곧, 모듈간 독립성이 높은 소프트웨어를 의미한다.
모듈의 독립성 - 추가 사항
- 독립성을 높히는 방안에는 결합도 및 응집도와 별개로 모듈의 크기 축소를 수행하는 방법이 있다.
(= 좌석을 운전자석, 조수석 등으로 더 상세히 모듈화 하는 것은 개발자의 몫이다.)
- 독립성이 높은 모듈의 특징은 다형성 및 OCP 원칙을 준수한 모듈이라는 것이다.
(OCP [Open-Closed Principle], 개방-폐쇄 원칙 : 확장에는 열려있고 변경에는 닫혀있어야 한다.)
결합도(Coupling)와 응집도(Cohesion)
응집도 (Cohesion)
- 하나의 모듈 내부의 요소들이 목적을 달성하기 위해 연결된 정도
결합도 (Coupling)
- 모듈과 모듈간의 상호의존 정도
- 하나의 모듈을 A라고 칭하면, A모듈 외부의 B, C와 상호작용을 위해 의존하는 정도이다.
결합도의 분류
1. 자료 결합도 (Data Coupling)
- 모듈간 인터페이스를 통해 상호작용하며, 단순한 자료를 주고 받는 경우
- 단순한 자료란, 추가적인 동작에 관여하지 않으며 기본 자료형을 띄는 자료를 의미한다.
e.g. int, boolean
2. 스탬프 결합도 (Stamp Coupling)
- 모듈간 인터페이스를 통해 상호작용하며, 자료 구조를 주고 받는 경우
- 자료 구조의 형식이나 내부 요소가 변경되면, 이를 참조하는 모든 모듈을 수정해야 한다.
e.g. array, list, object, set, 사용자 정의 클래스
3. 제어 결합도 (Control Coupling)
- 어떤 모듈이 다른 모듈의 내부적인 논리 흐름을 제어하는 값을 전달하는 경우
- 상위 모듈이 하위 모듈의 처리 절차를 알고있다는 의미가 되며, 이는 정보은닉 원칙에 위배된다.
- A모듈의 flag가 B모듈의 흐름에 관여한다면, 이는 A, B가 같은 기능에 관여함에도 분리되어 있음을 의미한다.
- 또한 한 모듈의 변경 시 다른 모듈에 미치는 영향을 고려해야 하며, 이를 위해 다른 모듈의 동작을 알고있어야 한다.
e.g. flag에 따른 case 분기처리
4. 외부 결합도 (External Coupling)
- 모듈이 외부 데이터를 참조하는 경우
- 외부 데이터란, 다른 모듈에 위치하는 데이터와 시스템 밖의 데이터 등을 모두 포함한다.
e.g. 프로토콜, 연산 모듈의 리턴 값 활용
개인적인 생각이다.
단순히 UserInfo Class를 전달받거나, Flag 변수를 전달받는 것은 각각 스탬프/외부 결합이다.
그럼에도 이는 외부 데이터를 참조한다고 표현할 수 있다.
따라서, 외부 데이터를 참조하는 경우 보다는, 외부의 추가 연산을 거친 데이터를 참조하는 경우로 여겼다.
참고 글들의 예시 또한 연산을 거친 값을 사용하는 경우를 표현했었다.
5. 공통 결합도 (Common Coupling)
- 여러 모듈이 공통 데이터 영역을 참조하는 경우
- 공통 데이터의 변경이 이를 참조하는 모든 모듈들에 영향을 끼친다.
e.g. 다수의 모듈이 같은 전역변수 값 참조
6. 내용 결합도 (Content Coupling)
- 특정 모듈이 다른 모듈의 내부 기능 및 데이터를 직접 참조하는 경우
- 참조 모듈의 수정이 영향을 미치며, 상호작용하는 모듈의 코드를 모두 알고있어야 하기 때문에 가장 좋지 않다.
e.g. 인터페이스/getter/ 리턴 값을 활용하지 않고 직접 참조
응집도의 분류
1. 기능적 응집도 (Functional Cohesion)
- 모듈을 구성하는 모든 요소들이 단일 목적(하나의 기능)을 수행하기 위해 구성되는 경우
e.g. 코사인 메서드
2. 순차적 응집도 (Sequential Cohesion)
- 모듈 내에서, 한 활동의 출력 값이 다음 활동의 입력 값으로 활용되는 경우
- 이는 결과적으로, 순차적인 흐름이 생긴다.
e.g. 파일을 읽고 처리
3. 교환적(통신적) 응집도 (Communicational Cohesion)
- 두 개의 이름으로 불린다.
- 요소들이 서로 다른 기능을 수행하지만, 동일한 입출력 값을 활용하는 경우
- 한 활동에서 나온 값이 다음 활동(다수의 모듈의)에 사용되지만, 다수의 모듈간의 수행 순서는 상관 없으므로 순차적 응집도와 구분한다.
4. 절차적 응집도 (Procedural Cohesion)
- 요소들이 서로 다른 기능을 수행하지만, 순차적으로 수행할 경우
- 다음 활동을 위해 데이터가 아닌 흐름 제어 요소가 전달되는 경우
e.g. 파일을 받아 접근 허가를 확인한 후에 파일을 읽음, 반환 값이 없는 메소드의 순차적인 호출
5. 시간적(일시적) 응집도 (Temporal Cohesion)
- 두개의 이름으로 불린다.
- 요소들이 순서에 상관없이 특정 시점에 수행되는 경우
e.g. 구동 시점에 변수를 초기화하는 경우, 에러 발생시 로그를 보내는 경우
6. 논리적 응집도 (Logical Cohesion)
- 한 모듈에서 처리되는 요소들이 논리적으로는 비슷하나 서로의 관계는 밀접하지 않은 경우
- 논리적으로 비슷이란, 유사한 성격을 갖거나 특정 분류기준에 포함되는 것을 의미
e.g. switch문을 사용하여 같은 목표를 달성하는 것 처럼 보이나, 막상 case간 다른 모듈을 실행
7. 우연적 응집도 (Coincidental Cohesion)
- 서로 관련이 없는 요소들로만 구성된 경우