- 좋은 객체지향 코드를 얻기 위해서 → 객체를 지향
- 객체가 수행하는 책임에 초점을 맞춰야 한다.
- 애플리케이션은 클래스로 구성되지만 메시지를 통해 정의된다.
1 협력과 메시지
클라이트-서버 모댈
- 클라이언트-서버 모델
- 메시지를 전송하는 객체를 클라이언트
- 메시지를 수신하는 객체를 서버
메시지와 메시지 전송
메시지와 메서드
- 메서드
- 메시지를 수신했을 때 실제로 실행되는 함수
- 동일한 이름의 변수에게 동일한 메시지를 전송하더라도 객체의 타입에 따라 실행되는 메서드가 달라질 수 있다.
- 객체는 메시지와 메서드라는 서로 다른 두 개념을 실행 시점에 연결해야 하기 때문에 컴파일 시점과 의미가 달라질 수 있다.
- 실해시점에 메시지와 메서드를 바인딩하는 것이 결함도를 낮출 수 있다.
퍼블릭 인터페이스와 오퍼레이션
시그니처
- 시그니처
- 메시지가 객체의 퍼블릭 인터페이스와 그 안에 포함될 오퍼레이션을 결정한다.
2 인터페이스와 설계 품질
- 최소한의 인터페이스 → 필요한 오퍼레이션만 존재
- 추상적인 인터페이스 → 어떻게가 아니라 무엇을 하는지 표현
- 최소한의 인터페이스와 추상적인 인터페이스를 설계할 수 있는 방법 → 책임 주도 설계
디미터 법칙
- 협력 경로 제한하라
- 오직 인접한 이웃하고만 말하라(오직 하나의 도트만 사용하라)
- 아래 조건을 만족하는 인스턴스에만 메시지를 전송하라
- this 객체
- 메서드의 매개변수
- this의 속성
- this의 속성인 컬렉션의 요소
- 메서드 내에서 생성된 지역 객체
- 내부 구현을 노출하지 않아 내부 구현에 결합되지 않게하는 법칙
묻지 말고 시켜라 법칙
- 정보 전문가에게 책임을 할당하게 한다.
- 정보를 요청하는 것이 아니라 원하는 작업을 시킴으로서 객체 내부를 탐색하지 않게하여 유연한 코드를 만든다.
- 유연한 코드 → 동일한 역할을 수행할 수 있는 다른 객체로 교체
의도를 드러내는 인터페이스
- 메서드의 이름은 "무엇"을 하는지 드러내는 이름으로 만들어라
- "어떻게" 하는지 드러내는 이름을 지으면 캡슐화 위반이다.
- 의도를 드러내는 선택자(Intention Revealing Selector)
- 의도를 드러내는 인터페이스(Intention Revealing Interface)
- 이름에 수행방법은 드러내지 말고 결과와 목적만 드러나게 해야 한다.
함께 모으기
3 원칙의 함정
앞에 나온 원칙은 절대적인 것이 아니다. 앞에서 소개한 원칙들이 현실에 부적합할 수 있다.
디미터 법칙은 하나의 도트를 강제하는 규칙이 아니다
- 디미터 법칙이 적용되는 경우는 객체의 내부 구조가 외부로 노출되는 경우로 한정된다.
- 설계는 트레이드오프의 산물이다.
결합도와 응집도의 충돌
4 명령-쿼리 분리 원칙
- 객체의 상태를 수정하는 것 → 명령
- 객체와 관련된 정보를 반환하는 것 → 쿼리
- 오퍼레이션이 명령이면서 쿼리이면 안된다.
- 명령과 쿼리를 분리해야 재사용성을 보장할 수 있다.
반복 일정의 명령과 쿼리 분리하기
- 명령과 쿼리를 뒤섞으면 실행 결과를 예측하기가 어려워질 수 있다.
명령-쿼리 분리와 참조 투명성
- 참조 투명성
- 표현식 e가 있을 때 e의 값으로 e가 나타나는 모든 위치를 교체해도 결과가 달라지지 않는 특징
- 명령-쿼리 분리를 통해 제한적이게 참조 투명성의 혜택을 누릴 수 있다.
- 함수형 프로그래밍
- 참조 투명성의 장점을 극대화
- 실행 결과를 이해하고 예측하기가 더 쉽다.
책임에 초점을 맞춰라
- 메시지를 선택하고 메시지를 처리할 객체를 선택하라