디미터 법칙은 무엇일까?
객체 안에 있는 메소드에 디미터 법칙에 위배되는 강한 결합도를 가진 메서드가 있다고 하자.
만약 이 메소드와의 결합도를 가진 로직 하나를 수정하면, 소스코드의 많은 곳에서 수정이 필요하다. 이러한 문제 때문에 디미터 법칙을 준수 해야한다.
디미터 법칙은 객체 지향 디자인 원칙중 하나이다. '최소 지식 원칙'이라는 말 처럼, 프로그래밍 시 객체 간 관계를 설정 할 때, 객체 간의 결합도를 낮추는 방법 중 하나이다.
→ 디미터 법칙의 핵심은 객체간 결합도를 낮추는 것이다.
→ 결합도를 낮추는 방법 : 객체 자신의 멤버 메소드를 이용하거나, 직접 생성한 객체의 메소드를 사용한다.
예를들어 A, B, C 객체가 있다고 가정하고, A는 B를 사용하고, B는 C를 사용한다. 이때 A는 C에 대해 알 필요가 없다는 것이다.
A에게 C는 그저 낯선 객체이다.
예를들어 우리가 자동차 경주를 하는 프로젝트를 한다고 가정해보자.
그러기 위해서는 경주용 자동차 클래스를 만들어야한다.
경주용 자동차를 의미하는 RacingCar
자동차를 의미하는 Car
기름을 의미하는 Oil
이렇게 세개의 클래스가 있다.
우선적으로 우린 자동자의 기록에 대한 클래스 Record 와 이런 기록을 갖고 있는 Car 클래스, 또한 경주용 자동차의미하는 RacingCar 클래스를 만들었다.
RacingCar 객체 안에는 Car 객체가 있다.
또한 Car 객체 안에는 자동차의 기록을 저장 있는 Oil 객체가 있다.
public class RacingCar {
Car car;
public Car getCar() {
return car;
}
public RacingCar(Car car) {
this.car = car;
}
}
//-----------------------------------------------------------------------------
public class Car {
private Oil oil;
public Oil getOil() {
return oil;
}
public Car(Oil oil) {
this.oil = oil;
}
}
//------------------------------------------------------------------------------
public class Oil {
private final int value;
public Oil(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
그렇다면 racingCar라는 경주용 자동차 객체가 있다. 이때 이 경주용 자동차의 남은 기름 잔량을 보려면 어떻게 해야할까?
racinCar.getCar().getOil().getValue();
의 형태로 생각 할 수 있다. 이것이 디미터 법칙을 위배한 것이다.
cars는 자신이 알고 싶어하는 자동차의 기록에 대한 정보만 알고 싶은데, .getRecord().getValue()의 과정을 거치면서 기존에 자신이 갖고 있지 않던 Record 에 대한 정보 또한 알게 된다.
그렇다면 어떻게 리팩터링을 하면 좋을까?
racingCar.getStoredOil()
의 형태로 남은 기름 잔량을 얻는 getStoredOil()라는 메서드를 만들어주면 된다.
public class RacingCar {
Car car;
public Car getCar() {
return car;
}
public RacingCar(Car car) {
this.car = car;
}
**public int getStoredOil(){
return car.getRemainingOil();
}**
//------------------------------------------------------------------------------
public class Car {
private Oil oil;
public Oil getOil() {
return oil;
}
public Car(Oil oil) {
this.oil = oil;
}
public int **getRemainingOil(**){
return oil.getValue();
}
}
//------------------------------------------------------------------------------
public class Oil {
private final int value;
public Oil(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
그렇다면 디미터 법칙을 사용하는 이점은 무엇일까?