디자인패턴/내 코드가 그렇게 이상한가요?

응집도란? - 내 코드가 그렇게 이상한가요? 5장 요약

얼룩와와 2024. 12. 24. 21:10

응집도란

"모듈* 내부에 있는 데이터와 로직 사이의 관계가 얼마나 강한지"를 말한다. 이때 모듈이란 클래스, 패키지, 레이어 등을 모두 포함하는데, 클래스로 생각해도 좋다. 

 

 

응집도를 낮추는 악마들 1 - static 메서드

static 메서드에서는 지역변수의 인스턴스 변수를 사용할 수 없다. 메서드는 클래스의 데이터, 즉 지역변수를 조작하는 것이 바람직한데 static으로 만들어졌다는 것에서부터 이미 클래스와는 직접적으로 상관이 없는 로직일 수도 있다는 뜻이다. 단, factory 패턴을 위한 생성 메서드는 예외다. 

 

 

응집도를 낮추는 악마들 2 - 인스턴스 변수를 사용하지 않는 메서드

1과 마찬가지로 인스턴스 변수를 사용하지 않는 메서드 역시 클래스의 응집도를 낮춘다.

 

 

응집도를 낮추는 악마들 3 - public 생성자

다음과 같이 경우에 따라 지역변수의 값을 다르게 초기화 하는 등 초기화 로직이 여기 저기에 흩어져 있는 것도 응집도가 낮은 구조이다. 

// GiftPoint 클래스
class GiftPoint {
	private static final int MIN_POINT = 0;
    final int value;
    
    GiftPoint(final int point) {
   	(...생략...)
    }
}
// 첫 번 째 회원 가입 케이스 - 일반 회원
GiftPoint standard = new GiftPoint(3000);

// 두 번 째 회원 가입 케이스 - 프리미엄 회원
GiftPoint premium = new GiftPoint(10000);

 

따라서 다음과 같이 생성자는 private으로 만들고 팩토리 매서드를 static으로 만드는 것이 바람직하다. 이렇게 함으로써 클래스에 초기화 로직을 모아둠으로써 변경이 수월해진다. 

// GiftPoint 클래스
class GiftPoint {
	private static final int MIN_POINT = 0;
    private static final int STANDARD_POINT = 3000;
    private static final int PREMIUM_POINT = 10000;
    final int value;
    
    private GiftPoint(final int point) {
   	(...생략...)
    }
    
    static GiftPoint forStandard() {
    	return new GiftPoint(STANDARD_POINT);
    }
    
    static GiftPoint forPremium() {
    	return new GiftPoint(PREMIUM_POINT);
    }
}

 

 

응집도를 낮추는 악마들 4 - `Common`, `Util` 클래스

클래스가 `Common`이나 `Util`이라는 이름을 가지게 되면 각종 static 메서드가 추가되게 된다. 재사용성을 높이려는 의도로 만든 것이겠지만 오히려 설계의 응집도를 높여야 재사용성이 높아진다. 다음과 같은 횡단 관심사(cross-cutting concern)만 static으로 만드는 것이 좋다. 

 

 

횡단 관심사(cross-cutting concern)

  • 로그 출력
  • 오류 확인
  • 디버깅
  • 예외 처리
  • 캐시
  • 동기화
  • 분산 처리

 

응집도를 낮추는 악마들 5 - 출력 매개변수

데이터를 조작하는 로직은 데이터는 같은 클래스에 위치해야 한다. 출력 매개변수, 즉 다른 클래스 인스턴스를 매개변수를 조작하는 메서드를 만들지 말아야 한다. 대신, 클래스 본인이 그 메서드를 가지도록 변경해야 한다. 

// 매개변수를 조작하고 있음 - 출력 매개변수
class ActorManager {
	void shift(Location location, int shiftX, int shiftY) {
    	location.x += shiftX;
        location.y += shiftY;
    }
}
// 데이터와 데이터를 조작하는 메서드가 같은 클래스에 위치하도록 변경
class Location {
	final int x;
    final int y;
    
	Location shift(final int shiftX, final int shiftY) {
    	final int nextX = x + shiftX;
        final int nextY = y + shiftY;
        return new Location(nextX, nextY);
    }
}

 

 

응집도를 낮추는 악마들 6 - 매개변수가 너무 많은 메서드

매개변수가 너무 많다는 것은 처리하고자 하는 로직이 많다는 것이다. 이는 원시 자료형을 버리고 각 데이터를 변수로 갖는 클래스를 만들어 활용하는 설계로 변경하는 것이 낫다는 신호일 수도 있다. 

 

 

응집도를 낮추는 악마들 7 - 메서드 체인

`.`으로 여러 메서드를 연결하는 것을 메서드 체인이라고 하는데, 여러 클래스를 거쳐 데이터에 접근하게 된다면 응집도가 낮다는 증거이다. 응집도가 낮기 때문에 여러곳에서 남의 데이터를 접근할 수 있고 코드가 중복될 수 있다. 이때는 인스턴스 변수를 private으로 변경해서 은닉하고, 외부에서 메서드를 호출하여 변경을 요청할 수 있도록 바꾸어야 한다.