작지만 꾸준한 반복

디미테르의 법칙, 왜? 본문

카테고리 없음

디미테르의 법칙, 왜?

iamjooon2 2023. 4. 5. 17:45

우테코 레벨로그에 중 디미테르의 법칙을 적어 냈다

 

저문이 계속해서 압박면접을 해주셔서 끝내 GG를 쳤는데..

집에 돌아오고 나서, 내 고민이 깊지 못했다는 생각이 들었다.

방학을 맞아 내 언어로 내 고민과 생각을 다시 정리해보려 한다.

 

돌이켜 생각해보면, 디미테르의 법칙을 처음 알게 된 것은 사다리 미션을 진행하면서였다

 

당시 내가 작성한 코드는 다음과 같다

 

public class Ladder {
    ....
    public Map<String, String> calculateResult(final Names names, final Prizes prizes) {
            Map<String, String> totalResult = new HashMap<>();
            for (int position = 0; position < names.size(); position++) {
                totalResult.put(names.getNames().get(position).getValue(), calculateSingleResult(prizes, position));
            }
            return new HashMap<>(totalResult);
    }
    ....
 }

 

 

찾아봐야 하는 부분은 바로 names.getNames().get(index).getValue() 였다.

 

저 부분만 메서드로 뽑아낸다면

public String getNameString(final Names names){
	return names.getNames().get(index).getValue();
}

// 풀어 쓸 때

public String getNames(final Names names){
    List<Name> names = names.getNames();
    Name name = names.get(index);
    String nameValue = name.getValue();
    return nameValue;
}

 

사람들의 이름을 일급 컬렉션으로 받은 Names를 받아 List<Name> 형태로 꺼내준 다음,

인덱스를 바탕으로 하나의 Name을 가져온다.

그 후, 출력을 위한 원시값인 String을 가져오는 메서드이다.

 

이 코드는, 디미터의 법칙을 위반한 코드다.

 

메서드만 보면.. 뭐 그냥 그런갑다 싶지만, 위 코드가 쓰인 곳은 Names 객체가 아닌 Ladder 객체였다

이 코드는 객체간의 결합도를 증가시킨다. 즉 Names와 Ladder간의 의존관계가 형성된 것이다.

다른 말로, Ladder에서 Names를 알고 있다

의존관계가 형성되면, 객체의 변경이 일어났을 때 의존성이 있는 다른 객체들이 영향을 받아 코드의 수정을 피할 수 없게 된다.

 

만일 위 코드에서 Names의 코드가 수정되어 getNames()의 메서드명이 바뀌었다고 가정한다면,

get(), getValue() 모두 영향을 받게 될 것이다.

이러한 현상은 개방 폐쇄 원칙(OCP)를 위반하며, 객체지향의 특징을 제대로 활용할 수 없게 된다.

 

만일 지금 다시 이 코드를 리팩터링 한다면, 아래와 같이 짤 것이다

public class Names {
    private final List<Name> names;
    
    ....
    
    public Name getNameByIndex(final int index){
        return names.get(index);
    }
    ....
}


public class Ladder {

    public Map<Name, Prize> calculateResult(final Names names, final Prizes prizes) {
        Map<Name, Prize> totalResult = new HashMap<>();
        for (int position = 0; position < names.size(); position++) {
            totalResult.put(names.getNameByIndex(position), calculateSingleResult(prizes, position));
        }
        return new HashMap<>(totalResult);
    }
    
}

 

Ladder에서 Names 객체 내부에 접근하는 것이 아닌, Names 객체 내부에서 순서에 맞는 이름을 찾도록 리팩터링했다.

(추가로 View를 위해 위한 원시값을 추출한 부분은 DTO를 이용하여 처리할 것이다.)

 

결국, 디미테르의 법칙은 객체간의 결합도를 낮춰줌을 알 수 있다.

 

객체지향을 지키기 위한 법칙들을 이해하기 위해서는 단순히 그 법칙만을 이해하는 것 보단, 연관된 객체지향의 지식들을 알고있어야 더 쉽게 접근할 수 있는 것 같다.

이 사실을 지금 객체지향의 사실과 오해 책을 읽으며 이를 뼈저리게 느끼고 있다.. 좀 더 빨리 읽을 걸 하는 후회도 든다.

이 디미테르의 법칙도 결국 "객체에 메시지를 보내라" , "캡슐화", "개방 폐쇄 원칙"과 연관되어있다고 생각한다