객체와 자료 구조는 다르다.
객체는 동작을 공개하고 자료를 숨긴다. 그래서 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기는 쉬운 반면, 기존 객체에 새 동작을 추가하기는 어렵다.
자료 구조는 별다른 동작 없이 자료를 노출한다. 그래서 기존 자료 구조에 새 동작을 추가하기는 쉬우나, 기존 함수에 새 자료 구조를 추가하기는 어렵다.
자료 추상화
- 자료를 공개하기 보다는 추상적인 개념으로 표현하는 편이 좋다
자료/객체 비대칭
- 객체 지향 코드에서 어려운 변경은 절차적인 코드에서 쉬우며, 절차적인 코드에서 어려운 변경은 객체 지향 코드에서 쉽다
- 새로운 함수가 아닌 새로운 자료 타입이 필요한 경우, 객체 지향 기법이 가장 적합하다
- 새로운 함수가 필요한 경우 절차적인 자료 구조가 좀 더 적합하다
- 단순한 자료 구조와 절차적인 코드를 필요에 따라 잘 배합하여 사용해야한다
디미터 법칙
- 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다
- 클래스 C의 메서드 f는 다음과 같은 객체의 메서드만 호출해야 한다
- 클래스 C
- f가 생성한 객체
- f 인수로 넘어온 객체
- C 인스턴스 변수에 저장된 객체
기차 충돌
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
-
다음과 같은 코드를 기차 충돌(train wreck)이라 부른다.
-
위 코드는 아래와 같이 나누는 편이 좋다
Option opts = ctxt.getOptions(); File scratchDir = opts.getScratchDir(); final String outputDir = scratchDir.getAbsolutePath();
-
Option, File은 모두 객체이므로 디미터 법칙을 위반한다(객체라면 내부 구조를 숨겨야 한다)
-
자료 구조로 함수 없이 공개 변수를 통해 제공한다면 디미터 법칙이 적용되지 않는다
final String outputDir = ctxt.options.scratchDir.absolutePath;
잡종 구조
- 절반은 객체, 절반은 자료 구조인 경우를 말한다
- 중요한 기능을 수행하는 함수도 있고, 공개 변수나 공개 조회/설정 함수도 있다.
- 잡종 구조는 새로운 함수는 물론이고, 새로운 자료 구조도 추가하기 어렵다
- 되도록 피하자!
구조체 감추기
-
기차 충돌 예제에서 디미터 법칙을 위반하지 않기 위해 구조체 감추기 방법을 사용할 수 있다
-
코드를 살펴보며 해당 코드의 동작이 무엇을 위한 것인지 파악해 단일 함수로 제공할 수 있다
Option opts = ctxt.getOptions(); File scratchDir = opts.getScratchDir(); final String **outputDir** = scratchDir.getAbsolutePath(); ... String outFile = **outputDir** + "/" + className.replace('.', '/') + ".class"; FileOutputStream fout = new FileOutputStream(outFile); BufferedOutputStream bos = new BufferedOutputStream(fout); // 임시 파일을 생성하기 위한 목적이다
-
ctxt에게 임시 파일을 생성하는 함수를 제공하도록 한다
BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
-
-
디미터 법칙을 위반하지 않으며, 복잡한 절차들을 간단한 메서드로 제공 가능하다
자료 전달 객체
- DTO(Data Transfer Object)라 한다
- 자료 구조체의 전형적인 형태는 공개 변수만 있고 함수가 없는 클래스이다
- 일반 적인 형태로 빈(bean)이 존재한다
- private 변수를 조회(getter)/설정(setter) 함수로 조작한다
활성 레코드
- DTO의 특수한 형태
- public 변수가 있거나 private 변수에 getter/setter가 존재한다
- save나 find 같은 탐색 함수도 제공한다
- 데이터베이스 테이블이나 다른 소스에서 자료를 직접 변환한 결과다
- 활성 레코드에는 비즈니스 규칙 메서드를 추가하지 않아야 한다
- 활성 레코드는 자료 구조로 취급하며 비즈니스 규칙을 담는 객체는 따로 생성하자