엔지니어로 가는 길

디미터 법칙: 객체의 내부 사정을 궁금해 하지 말 것 본문

프로그래밍/리팩터링

디미터 법칙: 객체의 내부 사정을 궁금해 하지 말 것

탐p슨 2022. 11. 12. 15:56
728x90

<클린 코드> 속 디미터 법칙에 대한 내용을 정리한 글이다.

디미터 법칙

모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 법칙이다. 구체적으로 예를 들자면 어떤 클래스 C의 메서드 M에서는 아래와 같은 메서드만 호출해야 한다.

 

  • 클래스 C의 메서드
  • 클래스 C의 인스턴스 변수로 저장된 객체의 메서드
  • 메서드 M 안에서 생성한 객체의 메서드
  • 메서드 M의 인자로 넘어온 객체의 메서드

아래의 코드를 살펴보자.

ctxt.getOptions().getScratchDir().getAbsolutePath(); // 아파치 프레임워크 속 코드

만약 위의 코드에서 ctxt가 객체라면(자료 구조가 아니라) 이는 디미터 법칙을 어긴 것이다.

 

메서드 체이닝이 중요한 것이 아니다.  디미터 법칙을 어겼는지를 결정하는 요소는 ctxt, Options, ScratchDir이 객체인지 자료 구조인지에 달렸다. 객체라면 내부 구조를 숨겨야 하므로 디미터 법칙의 위반이고, 자료구조라면 내부 구조를 노출하는 것이 당연하므로 디미터 법칙을 위반하지 않은 것이다.

(자료 구조는 함수 없이 공개 변수만 포함하고 객체는 비공개 변수와 공개 함수를 포함한다면 문제가 간단하겠지만 단순한 자료 구조에도 조회 함수와 설정 함수를 정의하라 요구하는 프레임워크와 표준이 존재한다.)

 

위 코드는 아래와 같이 나누는 게 좋다.

Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDirs();
…

그런데 왜 디렉터리의 절대 경로(getAbsolutePath)가 필요할까? 어디에 쓰려고? 위의 코드를 발췌한 곳에서 쭉 따라가 읽다보면 아래와 같은 내용이 나온다.

String outFile = outputDir + "/" + className.replace('.', '/') + ".class";
FileOutputStream fout = new FileOutputStream(outFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);

절대 경로는 임시 파일을 생성하기 위해 필요한 것임을 확인할 수 있다. 그렇다면 ctxt 객체에 임시 파일을 생성하라고 시키면 어떨까? 

BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);

ctxt는 내부 구조를 드러내지 않으며 모듈에서 해당 함수는 자신이 몰라야 하는 여러 객체를 탐색할 필요가 없다.

 

728x90
Comments