http://woowabros.github.io/study/2016/07/07/think_object_oriented.html
- 도메인이란? 사용자들이 관심을 가지고 있는 특정 분야나 주제를 말하며 소프트웨어는 도메인에 존재하는 문제를 해결하기 위해 개발된다.
- 클래스와 타입 사이의 차이는 꼭 이해해 두어야 합니다.
- 객체의 클래스는 그 객체가 어떻게 구현되느냐를 정의합니다. 클래스는 객체의 내부 상태와 그 객체의 연산에 대한 구현 방법을 정의합니다. 반면, 객체의 타입은 그 객체의 인터페이스, 즉 그 객체가 응답할 수 있는 요청의 집합을 정의합니다. 하나의 객체가 여러 타입을 가질 수 있고 서로 다른 클래스의 객체들이 동일한 타입을 가질 수 있습니다. 즉, 객체의 구현은 다를지라도 인터페이스는 같을 수 있다는 의미입니다.
- 객체지향의 세계는 협력하는 자율적인 객체들의 공동체
- 객체지향 설계의 첫 번째 목표는 훌륭한 객체를 설계하는 것이 아니라 훌륭한 협력을 설계하는 것
- 협력을 설계할 때는 객체보다는 메시지를 먼저 선택하고 그 후에 메시지를 수신하기에 적절한 객체를 선택한다.
- 객체가 수신한 메시지가 객체의 인터페이스를 결정한다
- 객체에게 책임을 할당하고 인터페이스를 결정할 때는 가급적 객체 내부의 구현에 대한 어떤 가정도 하지 말아야 한다. 객체가 어떤 책임을 수행해야 하는지를 결정한 후에야 책임을 수행하는 데 필요한 객체의 속성을 결정하라. 이것이 객체의 구현 세부 사항을 객체의 공용 인터페이스에 노출시키지 않고 인터페이스와 구현을 깔끔하게 분리할 수 있는 기본적인 방법이다.
- 객체지향이란 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해서 시스템을 분할하는 방법이다.
- 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.
- 프로그램 내의 객체는 현실 속의 객체에 대한 은유다.
- 책임은 객체에 의해 정의되는 응집도 있는 행위의 집합으로, 객체가 알아야 하는 정보와 객체가 수행할 수 있는 행위에 대해 개략적으로 서술한 문장이다. 즉, 객체의 책임은 ‘객체가 무엇을 알고 있는가(knowing)’와 ‘무엇을 할 수 있는가(doing)’로 구성된다.
- 객체의 책임을 이야기할 때는 일반적으로 외부에서 접근 가능한 공용 서비스의 관점에서 이야기한다. 즉, 책임은 객체의 외부에 제공해 줄 수 있는 정보(아는 것의 측면)와 외부에 제공해 줄 수 있는 서비스(하는 것의 측면)의 목록이다. 따라서 책임은 객체의 공용 인터페이스(public interface)를 구성한다.
- 테스트-주도 개발은 테스트를 작성하는 것이 아니라 책임을 수행할 객체 또는 클라이언트가 기대하는 객체의 역할이 메시지를 수신할 때 어떤 결과를 반환하고 그 과정에서 어떤 객체와 협력할 것인지에 대한 기대를 코드의 형태로 작성하는 것이다.
- 자율적인 책임의 특징은 객체가 ‘어떻게(how)’ 해야 하는가가 아니라 ‘무엇(what)’을 해야 하는가를 설명한다는 것이다.
- 훌륭한 객체지향 설계는 어떤 객체가 어떤 메시지를 전송할 수 있는가와 어떤 객체가 어떤 메시지를 이해할 수 있는가를 중심으로 객체 사이의 협력 관계를 구성하는 것이다.
- 묻지 말고 시켜라 (Tell, Don’t Ask)
- … 변경의 파급효과가 객체 내부로 캡슐화되기 때문에 두 객체 간의 결합도가 낮아진다.
- … 책임이 자율적일수록 객체의 응집도를 높은 상태로 유지하기가 쉬워진다.
- 지도 은유의 핵심은 기능이 아니라 구조를 기반으로 모델을 구축하는 편이 좀 더 범용적이고 이해하기 쉬우며 변경에 안정적이라는 것이다.
- 자주 변경되는 “기능”이 아니라 안정적인 “구조”를 따라 역할, 책임, 협력을 구성하라
- 미래에 대비하는 가장 좋은 방법은 변경을 예측하는 것이 아니라 변경을 수용할 수 있는 선택의 여지를 설계에 마련해 놓는 것이다.
- 좋은 설계는 나중에라도 변경할 수 있는 여지를 남겨 놓는 설계다.
- 일반적으로 기능을 수집하고 표현하기 위한 기법을 유스케이스 모델링이라고 하고 구조를 수입하고 표현하기 위한 기법을 도메인 모델링이라고 한다. 쉽게 예상할 수 있는 것처럼 두 가지 모델링 활동의 결과물을 각각 유스케이스와 도메인 모델이라고 한다.
- … 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다 [Evans 2003].
- 협력을 설계할 때는 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 해야 한다. 이 말은 메시지를 먼저 선택하고 그 후에 메시지를 수신하기에 적절한 객체를 선택해야 한다는 것을 의미한다. (215p)
- 설계를 간단히 끝내고 최대한 빨리 구현에 돌입하라. 머릿속에 객체의 협력 구조가 번뜩인다면 그대로 코드를 구현하기 시작하라. 설계가 제대로 그려지지 않는다면 고민하지 말고 실제로 코드를 작성해가면서 협력의 전체적인 밑그림을 그려보라. 테스트-주도 설계로 코드를 구현하는 사람들이 하는 작업이 바로 이것이다. 그들은 테스트 코드를 작성해 가면서 협력을 설계한다.
- 상속은 서브타이핑(subtyping)과 서브클래싱(subclassing)의 두 가지 용도로 사용될 수 있다. 서브클래스가 슈퍼클래스를 대체할 수 있는 경우 이를 서브타이핑이라고 한다. 서브클래스가 슈퍼클래스를 대체할 수 없는 경우에는 서브클래싱이라고 한다. 서브타이핑은 설계의 유연성이 목표인 반면 서브클래싱은 코드의 중복 제거와 재사용이 목적이다. 흔히 서브타이핑을 인터페이스 상속(interface inheritance)이라고 하고, 서브클래싱을 구현 상속(implementation inheritance)이라고 한다.