★LI7r웃으면Lr도죠οL넌장난σizr咬H도★

[Clean Code] 6.객체와 자료 구조

2021年02月21日

변수를 private으로 정의하여 변수에 의존하지 않게 만든다. 그렇다면 어째서 get, set 함수를 당연하게 public해 비공개 변수를 외부에 노출할까?

자료 추상화

구현을 감추려면 추상화가 필요하다. get, set함수로 변수를 다룬다고 클래스가 되지는 않는다.

추상 인터페이스를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있어야 진정한 의미의 클래스이다.

자료를 세세하게 공개하기 보다는 추상적인 개념으로 표현하는 편이 좋다.

자료/객체 비대칭

디미터 법칙

모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 법칙이다.

“클래스 C의 메서드 f는 다음과 같은 객체의 메서드만 호출해야 한다”

  • 클래스 C
  • f가 생성한 객체
  • f 인수로 넘어온 객체
  • C 인스턴스 변수에 저장된 객체

위 객체에서 허용된 메서드가 반환하는 객체의 메서드는 호출하면 안 된다.

let outputDir: String = ctct.getOptions().getScratchDir().getAbsolutePath()

기차 충돌

위와 같은 코드를 기차 충돌(train wreck)이라 부른다. 위 코드는 다음과 같이 나누는 편이 좋다.

let opts: Options = ctxt.getOptions()
let scratchDir: File = opts.getSratchDir()
let outputDir: String = scratchDir.getAbsolutePath()

위 예제가 디미터 법칙을 위반하는지 여부는 ctxt, options, scratchDir 이 객체인지 자료구조인지에 달렸다.

  • 객체라면 내부 구조를 숨겨야 하므로 디미터 법칙을 위반
  • 자료 구조라면 당연히 내부 구조를 노출하므로 디미터 법칙이 적용되지 않는다.

위 예제는 조회 함수를 사용하는 바람에 혼란을 일으킨다.

let outputDir = ctxt.options.scratchDir.absolutePath

와 같이 구현하면 디미터 법칙을 거론할 필요가 없다.

자료 구조

  • 무조건 함수 없이 공개 변수만 포함

객체

  • 비공개 변수와 공개 함수를 포함

로 구현한다면 문제는 훨씬 간단하다.

잡종 구조

이런 혼란으로 절반은 자료 구조, 절반은 객체인 잡종 구조가 나온다.

프로그래머가 함수나 타입을 보호할지 공개할지 확신하지 못해 어중간하게 내놓은 설계에 불과하다.

구조체 감추기

ctxt, options, scratchDir 가 객체라면? 위의 예제처럼 줄줄이 사탕으로 엮어선 안된다.

결론

객체는 동작을 공개하고 자료를 숨긴다.

  • 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기 쉽다.
  • 기존 객체에 동작을 추가하기는 어렵다.

자료구조는 별다른 동작 없이 자료를 노출한다.

  • 기존 자료 구조에 새 동작을 추가하기 쉽다.
  • 기존 함수에 새 자료 구조를 추가하기 어렵다.

새로운 자료 타입을 추가하는 유연성이 필요하면 객체가 더 적합하다.

새로운 동작을 추가하는 유연성이 필요하면 자료 구조와 절차적인 코드가 더 적합하다.