SW 개발 일반/클린 코드

디미터 법칙 (Law of Demeter)

growdai1y 2025. 3. 21. 03:32

소프트웨어 개발에서 결합도를 줄이는 것은 유지보수성과 확장성을 높이는 중요한 원칙입니다. 《Pragmatic Programmer》에서는 이를 설명하기 위해 디커플링(Decoupling)과 디미터의법칙(Law of Demeter, LoD)을 강조합니다. 이번 글에서는 디미터의 법칙이 왜 중요한지, 그리고 이를 지키지 않으면 어떤 문제가 발생하는지 실제 코드와 함께 살펴보겠습니다.


디미터의 법칙이란?

디미터의 법칙은 객체가 직접 알지 못하는 객체의 메서드를 호출하지 말라는 원칙입니다. 즉, 한 객체의 메서드는 다음 대상에 대해서만 직접적으로 메서드를 호출해야 합니다:

  • 자기 자신 (this)
  • 메서드의 매개변수로 전달된 객체
  • 직접 생성한 객체
  • 자기 자신이 소유한 구성 요소 객체

이 법칙을 따름으로써 불필요한 결합을 줄이고, 객체 간의 의존성을 최소화할 수 있습니다.


잘못된 코드 예시: 디미터 법칙 위반

아래 코드는 디미터의 법칙을 위반하는 전형적인 예제입니다.

public void plotDate(Date aDate, Selection aSelection) {
    TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone();
    // ...
}

위 코드는 aSelection 객체에서 getRecorder()를 호출한 후, 다시 getLocation()을 호출하고, 마지막으로 getTimeZone()을 호출합니다. 이 방식은 여러 계층의 객체에 직접 접근하는 방식으로, 특정 객체의 내부 구현을 직접적으로 의존하게 만듭니다.

문제점:

  1. 높은 결합도: Selection, Recorder, Location, TimeZone 네 개의 클래스가 서로 강하게 결합되어 있어, 하나의 변경이 다른 여러 클래스에 영향을 미칠 가능성이 높습니다.
  2. 유지보수 어려움: 만약 Location에서 getTimeZone()이 제거된다면, plotDate() 코드도 변경해야 합니다.
  3. 코드 가독성 저하: 너무 많은 메서드 체이닝으로 인해 코드가 복잡해지고, 어떤 객체가 실제로 필요한지 명확하지 않습니다.

올바른 코드 예시: 디미터 법칙 준수

디미터의 법칙을 따르면 객체의 직접적인 관계를 유지하며 불필요한 결합을 제거할 수 있습니다.

public void plotDate(Date aDate, TimeZone aTz) {
    // ...
}

// 호출 코드
plotDate(someDate, someSelection.getTimeZone());

여기서는 Selection 객체에 getTimeZone() 메서드를 추가하여 plotDate()가 불필요하게 RecorderLocation을 탐색할 필요가 없도록 하였습니다.

개선된 점:

  1. 결합도 감소: plotDate()Selection의 세부 사항을 몰라도 되고, SelectiongetTimeZone()의 구현을 변경하더라도 plotDate()에는 영향을 미치지 않습니다.
  2. 유지보수 용이: Location의 내부 구조가 바뀌더라도 Selection만 변경하면 되므로, 수정의 영향을 최소화할 수 있습니다.
  3. 가독성 향상: 필요한 데이터(TimeZone)만 직접 전달하기 때문에 코드가 단순해집니다.

마무리

메서드 호출이 get, get, get 형태로 체인처럼 연결된 코드를 만난다면, 한 번쯤 의심의 눈초리로 바라보는 것이 좋습니다. 객체지향 프로그래밍(OOP)에서는 get 메서드를 여러 번 호출하는 것보다는, 위임(Delegation)을 통해 적절한 객체에게 필요한 작업을 맡기는 것이 더 좋은 방향입니다. 이렇게 하면 자연스럽게 필요한 객체들이 추가되고, 디미터의 법칙에서 지적하는 문제들도 해결될 가능성이 높아집니다.

물론, "자연스럽다"라는 기준 자체가 결국 아는 만큼 보인다는 점에서 소프트웨어 개발의 어려움이 존재합니다. 하지만 이전보다 조금이라도 더 나아진 코드를 보며 느끼는 짜릿함은 쉽게 놓을 수 없죠. 어쩌면 그것이 우리가 계속해서 개발을 하는 이유일지도 모르겠습니다.

오늘도 파이팅입니다!

 

반응형

'SW 개발 일반 > 클린 코드' 카테고리의 다른 글

빈약한 객체 (Anemic Object)  (0) 2025.03.07
클린 코드: MAPPER 원칙  (0) 2025.02.05