디미터 법칙(Law of Demeter)

클린코드과정에서 코드리뷰를 통해 알게된 원칙이다. 흥미로운 원칙이기도 하고, 우아한 테크코스 기술블로그에서 심플하게 잘 정리해주셔서 정리해보았다.


객체간 결합도가 높아지게 될 경우 객체에 변경사항이 발생할 경우, 코드 곳곳에서 문제가 발생할 수 있다. 이는 유지보수의 어려움을 야기하게 된다.

디미터 법칙은 이런 문제를 지양하고자 하는 객체간 결합도를 낮추는 원칙이다.

1
2
3
4
5
void MyMethod(int length){
for(int i=0; i<length; i++){
play.cars().getCar(i)
}
}

이런 코드는 디미터 법칙을 위반하는 코드이다. 아래처럼 수정해야한다.

1
2
3
4
5
void MyMethod(int length){
for(int i=0; i<length; i++){
play.car(i)
}
}

그래서 디미터 법칙을 한 줄에 점 하나만 찍는다 라고 요약해서 말하기도 한다.

멀리 있는 객체에게는 메세지를 보내지 마라

한 줄에서 메서드를 하나만 호출하라는 이야기는 곧 객체간 관계에서 멀리있는 객체에게 메세지를 전달하지 말라는 이야기이기도 하다.

이 이야기는 객체는 내부적으로 보유하고 있거나 메세지를 통해 확보한 정보만 가지고 행동을 결정해야한다고 정리할 수 있다. 다른 객체를 탐색해서 어떤 행동을 하는 것은 지양해야 한다고 한다.

그래서 디미터 법칙은 한 객체가 알야아 하는 다른 객체를 최소한으로 유지한다는 측면에서 최소 지식 원칙(Principle of least knowleadge)라고도 한다.

디미터 법칙에서 호출할 수 있는 메서드들

  • 객체 자신의 메서드
  • 파라미터로 넘어온 객체의 메서드
  • 메서드 내부에서 생성, 초기화된 객체의 메서드
  • 인스턴스 변수로 갖고있는 객체의 메서드

위의 메서드들에 대한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Demeter {
private Member member;

public myMethod(OtherObject other) {
// ...
}

public okLawOfDemeter(Paramemter param) {
myMethod(); // 1. 객체 자신의 메서드
param.paramMethod(); // 2. 메서드의 파라미터로 넘어온 객체들의 메서드
Local local = new Local();
local.localMethod(); // 3. 메서드 내부에서 생성, 초기화된 객체의 메서드
member.memberMethod(); // 4. 인스턴스 변수로 가지고 있는 객체가 소유한 메서드
}
}

출처 : Javable - 디미터 법칙(Law of Demeter)