프로젝트

일반

사용자정보

GRASP 패턴: High Cohesion (높은 응집도)

Prof. Jong Min Lee이(가) 약 한달 전에 추가함

GRASP 패턴: High Cohesion (높은 응집도) - 간단한 설명과 예시

핵심 아이디어: 클래스가 관련된 책임들만 가져야 하며, 너무 많은 관련 없는 책임을 가지지 않도록 설계합니다. 하나의 클래스는 하나의 명확한 목적을 가져야 하며, 그 목적을 달성하기 위한 책임들을 함께 묶어야 합니다.

간단한 설명:

높은 응집도는 클래스 내부의 요소들(속성, 메서드)이 서로 얼마나 관련되어 있는지를 나타내는 정도입니다. 응집도가 높은 클래스는 특정 목적을 달성하기 위해 밀접하게 관련된 책임들만을 수행합니다. 이는 클래스를 이해하고 유지보수하기 쉽게 만들고, 변경이 발생했을 때 다른 클래스에 미치는 영향을 줄여줍니다. 반대로 응집도가 낮은 클래스는 여러 가지 관련 없는 책임을 가지므로 이해하기 어렵고, 변경에 취약하며, 재사용성이 떨어집니다.

예시:

하나의 클래스가 사용자 정보 관리, 로깅, 환경 설정 관리의 세 가지 관련 없는 책임을 가지고 있다고 가정해 봅시다.

class Utility {
    // 사용자 정보 관리 책임
    public void saveUser(String userId, String userName) {
        // 사용자 정보 저장 로직
        System.out.println("사용자 정보 저장: ID=" + userId + ", 이름=" + userName);
    }

    public String getUserName(String userId) {
        // 사용자 이름 조회 로직
        System.out.println("사용자 " + userId + " 이름 조회");
        return "사용자 이름";
    }

    // 로깅 책임
    public void logInfo(String message) {
        // 정보 로그 기록 로직
        System.out.println("[INFO] " + message);
    }

    public void logError(String message) {
        // 에러 로그 기록 로직
        System.err.println("[ERROR] " + message);
    }

    // 환경 설정 관리 책임
    public String getConfiguration(String key) {
        // 환경 설정 값 조회 로직
        System.out.println("환경 설정 " + key + " 조회");
        return "설정 값";
    }

    public void setConfiguration(String key, String value) {
        // 환경 설정 값 저장 로직
        System.out.println("환경 설정 " + key + " 저장: " + value);
    }
}

public class Client {
    public static void main(String[] args) {
        Utility utility = new Utility();
        utility.saveUser("123", "홍길동");
        utility.logInfo("사용자 로그인");
        String configValue = utility.getConfiguration("database.url");
    }
}

위의 Utility 클래스는 사용자 관리, 로깅, 환경 설정 관리라는 서로 관련 없는 세 가지 책임을 모두 가지고 있습니다. 이는 낮은 응집도의 예시입니다.

높은 응집도 패턴을 적용하면 각 책임을 별도의 클래스로 분리할 수 있습니다.

// 사용자 정보 관리 책임만 담당
class UserManager {
    public void saveUser(String userId, String userName) {
        System.out.println("사용자 정보 저장: ID=" + userId + ", 이름=" + userName);
    }

    public String getUserName(String userId) {
        System.out.println("사용자 " + userId + " 이름 조회");
        return "사용자 이름";
    }
}

// 로깅 책임만 담당
class Logger {
    public void logInfo(String message) {
        System.out.println("[INFO] " + message);
    }

    public void logError(String message) {
        System.err.println("[ERROR] " + message);
    }
}

// 환경 설정 관리 책임만 담당
class ConfigurationManager {
    public String getConfiguration(String key) {
        System.out.println("환경 설정 " + key + " 조회");
        return "설정 값";
    }

    public void setConfiguration(String key, String value) {
        System.out.println("환경 설정 " + key + " 저장: " + value);
    }
}

public class Client {
    public static void main(String[] args) {
        UserManager userManager = new UserManager();
        Logger logger = new Logger();
        ConfigurationManager configManager = new ConfigurationManager();

        userManager.saveUser("123", "홍길동");
        logger.logInfo("사용자 로그인");
        String configValue = configManager.getConfiguration("database.url");
    }
}

변경된 설계에서는 각 클래스가 명확하고 관련된 책임만을 가지므로 높은 응집도를 갖습니다.

높은 응집도의 장점:

  • 이해 용이성: 각 클래스가 하나의 명확한 목적을 가지므로 코드를 이해하기 쉽습니다.
  • 유지보수 용이성: 특정 기능 변경 시 관련된 클래스만 수정하면 되므로 유지보수가 용이합니다.
  • 재사용성 향상: 각 클래스가 특정 역할에 집중하므로 다른 컨텍스트에서 재사용될 가능성이 높아집니다.
  • 낮은 결합도: 각 클래스가 독립적인 책임을 가지므로 다른 클래스와의 의존성이 줄어들어 결합도가 낮아집니다.
  • 안정성 향상: 한 클래스의 변경이 다른 unrelated 된 기능에 영향을 미칠 가능성이 줄어들어 시스템의 안정성이 향상됩니다.

결론적으로, 높은 응집도 패턴은 클래스를 설계할 때 중요한 원칙이며, 클래스가 명확하고 관련된 책임만을 갖도록 함으로써 코드의 품질을 향상시키는 데 기여합니다.