800===Dev Concepts and License/소프트웨어 아키텍쳐

[소프트웨어 공학] - Myers가 구분한 응집도 개념 완전 정복하기 🧩

블로글러 2025. 2. 9. 01:58

안녕하세요, 소프트웨어 엔지니어링의 핵심 개념 중 하나인 '응집도(Cohesion)'에 대해 알아볼까요? 특히 오늘은 소프트웨어 공학의 선구자인 Glenford J. Myers와 Larry Constantine이 정의한 7가지 응집도 유형에 대해 깊이 있게 살펴보겠습니다.

여러분이 주방 용품을 정리하는 상황을 생각해보세요.

  • 모든 조리 도구가 무작위로 서랍에 던져져 있다면? 필요한 도구를 찾기 어렵겠죠 (낮은 응집도)
  • 칼은 칼끼리, 조리 도구는 도구끼리, 양념은 양념끼리 분류되어 있다면? 훨씬 효율적입니다 (높은 응집도)

왜 응집도가 필요한가?

응집도는 소프트웨어 설계에서 다음과 같은 문제들을 해결합니다:

  1. 유지보수 문제: 낮은 응집도의 코드는 이해하기 어렵고 변경 시 예측하지 못한 부작용이 발생할 수 있습니다.
  2. 재사용성 저하: 응집도가 낮은 모듈은 다른 프로젝트에서 재사용하기 어렵습니다.
  3. 테스트 복잡성: 여러 기능이 뒤섞인 모듈은 개별적으로 테스트하기 어렵습니다.
  4. 코드 이해도 감소: 한 모듈이 여러 관련 없는 작업을 수행하면 개발자가 코드를 이해하는 데 시간이 더 오래 걸립니다.

기본 원리

Myers와 Constantine은 모듈 내부 요소들의 관련성에 따라 7단계의 응집도를 정의했습니다. 응집도가 낮은 것부터 높은 순서로 살펴봅시다.

1. 우연적 응집도 (Coincidental Cohesion)

모듈 내 요소들이 아무 연관성 없이 우연히 묶여 있는 상태입니다.

class UtilityClass {
    public static double calculateTax(double amount) { ... }
    public static void printReport() { ... }
    public static boolean validateEmail(String email) { ... }
    public static void connectToDatabase() { ... }
}

이 코드의 문제점은 서로 관련 없는 함수들이 하나의 모듈에 무작위로 포함되어 있다는 것입니다. 이러한 설계는 코드 이해를 어렵게 하고 유지보수성을 저하시킵니다.

2. 논리적 응집도 (Logical Cohesion)

요소들이 논리적으로 같은 범주에 속하지만, 실제 기능적으로는 연관성이 낮습니다.

class InputOperations {
    public static void readFromKeyboard() { ... }
    public static void readFromFile() { ... }
    public static void readFromNetwork() { ... }
    public static void readFromDatabase() { ... }
}

모든 기능이 '입력'이라는 논리적 카테고리에 속하지만, 실제 기능적 연관성은 낮습니다.

3. 시간적 응집도 (Temporal Cohesion)

특정 시점에 함께 실행되는 요소들이 한 모듈에 포함됩니다.

class Startup {
    public void initialize() {
        initializeDatabase();
        loadUserSettings();
        checkLicense();
        displaySplashScreen();
    }

    private void initializeDatabase() { ... }
    private void loadUserSettings() { ... }
    private void checkLicense() { ... }
    private void displaySplashScreen() { ... }
}

이 모듈의 함수들은 프로그램 시작 시점에 실행된다는 시간적 특성만 공유합니다.

4. 절차적 응집도 (Procedural Cohesion)

특정 절차나 순서에 따라 실행되는 요소들이 한 모듈에 포함됩니다.

class OrderProcessor {
    public void processOrder() {
        getCustomerData();
        validateData();
        updateDatabase();
        sendConfirmationEmail();
    }

    private void getCustomerData() { ... }
    private void validateData() { ... }
    private void updateDatabase() { ... }
    private void sendConfirmationEmail() { ... }
}

이 모듈의 함수들은 특정 순서대로 실행되지만, 각 함수의 출력이 다음 함수의 입력으로 직접 사용되지는 않습니다.

5. 통신적 응집도 (Communicational Cohesion)

같은 입력 데이터를 사용하거나 같은 출력 데이터를 생성하는 요소들이 한 모듈에 포함됩니다.

class CustomerProcessor {
    private Customer customer;

    public CustomerProcessor(Customer customer) {
        this.customer = customer;
    }

    public boolean validateCustomer() { ... }
    public double calculateDiscount() { ... }
    public Invoice generateInvoice() { ... }
}

모든 함수가 동일한 고객 데이터를 사용합니다.

6. 순차적 응집도 (Sequential Cohesion)

한 요소의 출력이 다른 요소의 입력으로 직접 사용되는 경우입니다.

class OrderCalculator {
    public OrderSummary processOrder(OrderData data) {
        ProcessedOrderData processedData = processOrderData(data);
        TotalWithTax totalWithTax = calculateTotalWithTax(processedData);
        return generateOrderSummary(totalWithTax);
    }

    private ProcessedOrderData processOrderData(OrderData data) { ... }
    private TotalWithTax calculateTotalWithTax(ProcessedOrderData data) { ... }
    private OrderSummary generateOrderSummary(TotalWithTax total) { ... }
}

각 함수의 출력이 다음 함수의 입력으로 직접 사용됩니다.

7. 기능적 응집도 (Functional Cohesion)

모든 요소가 단일 기능을 수행하기 위해 밀접하게 연관되어 있는 상태입니다.

class InterestCalculator {
    public double calculateInterest(Loan loan) {
        double rate = determineRate(loan);
        double timeValue = applyTimeValue(loan.getDuration());
        return computeFinalAmount(loan.getPrincipal(), rate, timeValue);
    }

    private double determineRate(Loan loan) { ... }
    private double applyTimeValue(int months) { ... }
    private double computeFinalAmount(double principal, double rate, double timeValue) { ... }
}

모든 함수가 이자 계산이라는 하나의 목적을 위해 존재합니다.

실제 예제

응집도 개념을 실제 비즈니스 환경에 적용해 봅시다.

기본 사용법

현실 세계의 소프트웨어 프로젝트에서는 다양한 수준의 응집도가 혼합되어 있지만, 높은 응집도를 목표로 합니다.

// 낮은 응집도 (우연적 응집도)
class DataHandler {
    public void saveUser() { ... }
    public void calculateTax() { ... }
    public void printReport() { ... }
    public void sendEmail() { ... }
}

// 높은 응집도 (기능적 응집도)
class UserRepository {
    public void saveUser() { ... }
    public User findUserById(int id) { ... }
    public void updateUser(User user) { ... }
    public void deleteUser(int id) { ... }
}

실전 활용

다음은 응집도 개선을 통한 실제 효과를 보여주는 예시입니다:

상황 낮은 응집도 접근법 높은 응집도 접근법 개선효과
사용자 관리 시스템 하나의 대형 UserManager 클래스가 모든 기능 처리 UserRepository, UserService, UserValidator 등으로 분리 유지보수 40% 향상, 테스트 용이성 증가
결제 처리 모듈 결제, 환불, 세금 계산 등이 하나의 모듈에 구현 각 책임별 독립 모듈로 분리(PaymentProcessor, RefundHandler, TaxCalculator) 코드 재사용성 70% 증가, 버그 발생률 감소
데이터 분석 도구 데이터 로딩, 분석, 시각화 기능이 혼합된 모듈 각 기능별 모듈로 세분화하고 명확한 인터페이스 정의 확장성 향상, 새로운 기능 추가 시간 50% 단축

주의사항 및 팁 💡

⚠️ 이것만은 주의하세요!

  1. 과도한 분리 지양

    • 지나치게 작은 모듈로 분리하면 오히려 복잡성이 증가할 수 있습니다.
    • 적절한 크기와 기능적 완전성을 갖춘 모듈을 설계하세요.
  2. 응집도와 결합도의 균형

    • 응집도를 높이려다 모듈 간 결합도가 증가하는 경우를 조심하세요.
    • 인터페이스와 추상화를 통해 결합도는 낮추면서 응집도는 높이는 설계를 지향하세요.
  3. 리팩토링 시 주의점

    • 기존 코드의 응집도를 높이기 위한 리팩토링은 기능 변경 없이 진행해야 합니다.
    • 테스트 코드를 통해 리팩토링 전후의 동작이 동일함을 검증하세요.

💡 꿀팁

  • '단일 책임 원칙(SRP)'을 적용하면 자연스럽게 기능적 응집도를 높일 수 있습니다.
  • 코드 리뷰 시 "이 클래스/모듈은 정확히 무슨 일을 하나요?"라는 질문에 한 문장으로 대답할 수 없다면 응집도가 낮을 가능성이 높습니다.
  • 메서드 이름이 'and'나 'or'를 포함한다면 여러 책임을 가진 징후일 수 있습니다.
  • 테스트하기 어려운 코드는 대개 응집도가 낮은 코드입니다.

마치며

지금까지 Myers가 정의한 7가지 응집도 유형에 대해 알아보았습니다. 응집도는 단순한 이론적 개념이 아니라 실제 소프트웨어 설계와 개발에 직접적인 영향을 미치는 중요한 원칙입니다.

우연적 응집도(가장 약함)에서 기능적 응집도(가장 강함)까지의 스펙트럼을 이해하고 적용함으로써, 더 유지보수하기 쉽고, 테스트하기 쉽고, 이해하기 쉬운 소프트웨어를 만들 수 있습니다.

여러분의 코드에서 응집도를 점검하고 개선해보세요. 처음에는 어렵게 느껴질 수 있지만, 지속적인 노력을 통해 코드 품질을 크게 향상시킬 수 있습니다.

혹시 응집도 개선에 관한 실제 경험이나 질문이 있으시면 댓글로 남겨주세요.

참고 자료 🔖

  • Stevens, W., Myers, G., & Constantine, L. (1974). "Structured Design"
  • Martin, Robert C. (2008). "Clean Code: A Handbook of Agile Software Craftsmanship"
  • Fowler, Martin (2018). "Refactoring: Improving the Design of Existing Code"

#소프트웨어공학 #응집도 #모듈설계 #코드품질

728x90
반응형