Java

[Java] 디미터의 원칙

반응형

디미터의 원칙이란?

특정 객체가 다른 객체의 정보를 너무 많이 알다 보면 결합도가 높아지면서 문제를 야기한다. 이러한 문제를 개선하기 위해 객체에게 자료를 숨기는 대신 함수를 공개하는 것을 디미터의 원칙이다.

본인이 아니라 협력하는 객체의 내부 구조에 대해 알다보면 결합도가 생기는데, 이때 강하게 결합되지 않도록 협력 경로를 제한하는 원칙이다.

즉, 자기 소유의 장난감, 자기가 만든 장난감, 그리고 누군가 자기에게 준 장난감하고만 놀 수 있다. 하지만 절대 장난감의 장난감과 놀면 안 된다.

객체 지향 생활체조 원칙의 한줄에 점을 한 개만 찍는다. 원칙으로도 불리운다.

 

 

디미터의 원칙을 지키지 않는 경우

더 자세히 살펴보자.

보통 getter()를 사용해서 다른 객체의 값을 많이 가져오는데, 본인을 제외한 다른 객체를 탐색해서 어떤 일이 발생하면 안 된다는 것을 명심해야 한다.

아래는 getter()를 사용해 작업을 진행하는 디미터의 원칙을 지키지 않는 경우이다.

@Getter
public class Bag {
    private final String Notebook;
}

@Getter
public class Notebook {
    private final String brand;
    private final String weight;
}
public class Study {
    private static final String NOTEBOOK = "apple";

    public void validateNotebook(Bag bag) {
        if (NOTEBOOK.equals(bag.getNotebook().getBran()) {
            //~~
        }
    }
}

가방에는 노트북이 있고, 노트북은 브랜드와 무게를 가지고 있다.

공부하기 위해 apple 브랜드의 노트북이 필요한 나는 가방 안의 노트북의 브랜드가 apple인지 확인하고 싶다.

나는 @Getter 애노테이션을 사용해 브랜드를 가져와 비교할 수 있지만, Bag 객체뿐만 아니라 Notebook 객체의 값까지 확인해 사용하고 있다.

위에서 언급했듯이 나는 '장난감의 장난감'과 놀고 있는 셈이다. 그로 인해 자동적으로 .(참조)을 여러 번 찍게 된다.

그래서 객체 지향 체조 원칙을 지켜나가다 보면 자동스럽게 방지될 수 있다고 생각한다.

 

 

디미터의 원칙을 지키는 경우

디미터의 원칙을 지키기 위해서 아래처럼 변경해보자.

  1. Getter를 없애고
  2. 내가 실행하는 함수를 Bag 클래스에서 수행해 결괏값을 반환
@Getter
public class Bag {
    private final String Notebook;
}

public class Notebook {
    private static final String NOTEBOOK = "apple";

    private final String brand;
    private final String weight;

    public boolean checkNotebook() {
        return NOTEBOOK.equals(brand);
    }
}
public class Study {

    public void validateNotebook(Bag bag) {
        if (bag.checkNotebook()) {
            //~~
        }
    }
}

위처럼 변경하면 Study 클래스의 validateNotebook() 메서드에서 Bag 객체의 checkNotbook() 메서드 하나만 사용해 원하는 결과를 얻을 수 있기 때문에 다른 객체를 탐색해 부가적인 일이 나지 않는다. 그래서 .(참조)이 줄어드면서 디미터의 법칙을 준수할 수 있어진다.

 

아래처럼 따로 비교해보면 더 직관적으로 변한 것을 확인할 수 있다.

NOTEBOOK.equals(bag.getNotebook().getBran()

bag.checkNotebook()

 

 

결론

간단히 말하면 아래의 메소드만 호출하는 규칙들을 지키며 결합도를 낮추는 법칙이다.

  1. 객체 자신의 메소드들
  2. 파라미터로 넘어온 객체들의 메소드들
  3. 메소드 안에서 생성되거나 초기화된 메소드들
  4. 자신이 직접 소유하는 객체의 메소드들
  5. 파라미터로 접근이 가능한 전역 변수의 메소드들

 

추가적으로 사용하는 객체가 일급 컬렉션인 경우 문제가 발생할 수 있다고 하는데 이 경우는 추후 더 조사해 보겠다..

 

 

참조

https://tecoble.techcourse.co.kr/post/2020-06-02-law-of-demeter/

https://mangkyu.tistory.com/147

https://hongjinhyeon.tistory.com/138

 

반응형

'Java' 카테고리의 다른 글

[Java] 인터페이스  (0) 2021.08.07
[Java] Object(toString(), equals(), hashCode())  (0) 2021.08.03
[Java] StringBuilder vs StringBuffer  (0) 2021.08.03
[Java] Solid란?  (0) 2021.07.28
[Java] 다형성, 캐스팅, 추상 클래스, 추상 메서드  (0) 2021.06.22