응집도(Cohesion)
응집도는 하나의 모듈이 얼마나 단일한 목적에 집중되어 있는지를 나타낸다.
모듈 내부의 요소들이 서로 얼마나 밀접하게 관련되어 있는지를 측정하는 척도이다.
높은 응집도는 모듈이 하나의 명확한 책임을 가지고 있음을 의미하며, 이는 좋은 설계의 특징이다.
특징 및 기능
- 모듈의 독립성을 나타냄
- 유지보수성과 재사용성 향상에 기여
- 모듈의 품질을 평가하는 지표로 사용
응집도의 종류
낮은 응집도부터 높은 응집도 순
우연적 응집도(Coincidental Cohesion):
서로 관련 없는 기능들이 한 모듈에 모여있는 경우.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// 우연적 응집도의 예 class Utility { public void calculateTax() { } public void formatDate() { } public void validateEmail() { } public void connectToDatabase() { } } // 개선된 버전 - 각 책임을 분리 class TaxCalculator { public void calculateTax() { } } class DateFormatter { public void formatDate() { } } class EmailValidator { public void validateEmail() { } }
논리적 응집도(Logical Cohesion):
논리적으로 비슷한 기능을 수행하지만 실제로는 다른 작업들을 하나의 모듈에서 처리하는 경우.시간적 응집도(Temporal Cohesion):
특정 시점에 함께 실행되어야 하는 기능들이 한 모듈에 있는 경우.절차적 응집도(Procedural Cohesion):
여러 작업이 특정 순서로 실행되어야 할 때 이를 하나의 모듈에서 처리하는 경우.통신적 응집도(Communicational Cohesion):
동일한 데이터를 처리하는 여러 작업들이 하나의 모듈에 있는 경우.순차적 응집도(Sequential Cohesion):
한 작업의 출력이 다른 작업의 입력으로 사용되는 경우.기능적 응집도(Functional Cohesion):
가장 높은 수준의 응집도로, 모듈의 모든 요소가 단일 목적을 위해 존재하는 경우.1 2 3 4 5 6 7 8 9 10 11 12 13
// 기능적 응집도의 예 class PasswordHasher { private final String salt; private final int iterations; public String hashPassword(String password) { String salted = addSalt(password); return applyHash(salted, iterations); } private String addSalt(String input) { } private String applyHash(String input, int iterations) { } }
응집도 측정 방법
LCOM (Lack of Cohesion of Methods):
클래스의 메서드들이 얼마나 공통된 인스턴스 변수를 사용하는지 측정한다.LCOM4:
메서드와 속성 간의 그래프를 만들어 응집도를 측정한다.
응집도를 높이기 위한 전략
단일 책임 원칙(Single Responsibility Principle) 적용:
관련 없는 기능 분리:
응집도가 낮은 클래스 리팩토링:
도구
- SonarQube: 코드 품질 및 응집도 분석
- JArchitect: Java 코드 분석
- NDepend:.NET 코드 분석
- Structure101: 아키텍처 분석
주의사항
- 과도한 분리는 오히려 복잡성을 증가시킬 수 있다.
- 응집도와 결합도는 함께 고려되어야 한다.
- 완벽한 기능적 응집도를 달성하는 것은 현실적으로 어려울 수 있다.
권장사항
- 클래스와 메서드의 책임을 명확히 정의한다.
- 관련 없는 기능은 과감히 분리한다.
- 정기적인 코드 리뷰를 통해 응집도를 검토한다.
- 단일 책임 원칙을 항상 고려한다.
- 응집도 메트릭을 모니터링하고 개선한다.