디미터 법칙
디미터 법칙은 모듈은 자신이 조작하는 객체의 속내용을 몰라야 한다는 법칙이다.
앞의 포스팅에서 봤듯이, 객체는 자료를 숨기고 함수를 공개한다.
즉, 객체는 조회 함수로 내부 구조를 공개하면 안 된다는 의미이다.
좀 더 정확히 표현하면 디미터 법칙은 클래스 C의 메소드메서드 f는 다음과 같은 객체의 메소드만 호출해야 한다.
다음 코드는 디미터 법칙을 어기는 듯이 보인다.
getOptions() 함수가 반환하는 객체의 getScratchDir() 함수를 호출한 후 getScratchDir() 함수가 반환하는 객체의 getAbsolutePath() 함수를 호출하기 때문이다.
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
위와 같은 코드를 '기차 충돌(train wreck)' 이라고 부른다.
일반적으로 조잡하다 여겨지는 방식이므로 피하는 편이 좋다.
그리고 아래와 같이 나누는 게 좀 더 좋다.
Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();
위 코드는 디미터 법칙을 위반하는지에 대한 여부는 ctxt, options, scratchDir이 객체인지 아니면 자료구조인지에 따라 달렸다.
객체라면 내부 구조를 숨겨야 하므로 디미터 법칙 위반이다.
하지만 자료 구조라면 당연히 내부 구조를 노출하므로 디미터 법칙이 적용되지 않는다.
그런데 위 코드는 조회 함수를 사용하므로 혼란을 일으킨다.
코드를 다음과 같이 구현하면 디미터 법칙이 거론될 필요가 없어진다.
final String outputDir = ctxt.options.scratchDir.absolutePath;
만약 ctx, options, scratchDir이 진짜 객체라면 위 코드처럼 줄줄이 소시지로 엮어서 표현하면 안 된다.
그럼 어떻게 표현해야 할까?
ctxt.getAbsolutePathOfScratchDirectoryOption();
ctxt.getScratchDirectoryOption().getAbsolutePath()
첫 번째 방법은 ctxt 객체에 공개해줘야 할 메소드가 너무 많다.
두 번째 방법은 getScratchDirectoryOption()이 객체가 아니라 자료 구조를 반환한다고 가정한다.
두 방법 다 딱히 좋은 방법이 아니다. 그러므로 아래 코드와 같이 ctxt 객체에 임시파일을 생성하라고 시켜야 한다.
BufferedOutPutStream bos = ctxt.createScratchFileStream(classFileName);
이러면 객체가 할 적당한 행동이다. ctxt는 내부 구조를 드러내지 않고, 모듈에서 해당 함수는 자신이 몰라야 하는 여러 객체를 가지고 있을 필요가 없다.
'클린 코드' 카테고리의 다른 글
[클린 코드] 오류 처리(1) (0) | 2022.02.03 |
---|---|
[클린 코드] 객체와 자료구조(4) (0) | 2022.01.27 |
[클린 코드] 객체와 자료구조(2) (0) | 2022.01.26 |
[클린 코드] 객체와 자료구조(1) (0) | 2022.01.19 |
[클린 코드] 형식 맞추기(2) (0) | 2022.01.17 |