> For the complete documentation index, see [llms.txt](https://develop-footprint.gitbook.io/o/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://develop-footprint.gitbook.io/o/programming/object/4.md).

# 4장: 설계 품질과 트레이드오프

## 객체 지향 설계

* 객체지향 설계란 올바른 객체에게 올바른 **책임**을 할당하면서 낮은 결합도와 높은 응집도를 가진 구조를 창조하는 활동이다.
* 상태를 기준으로 객체를 분할하는 방법과 책임을 기준으로 객체를 분할하는 방법이 있을 수 있다. 전자는 객체를 독립된 데이터 덩어리로 바라보고 후자는 객체를 협력하는 공동체의 일원으로 바라본다.
* 객체의 상태는 구현에 속하고 변하기 쉬우며, 상태를 기준으로 객체를 설계할 경우 구현에 관한 세부 사항이 객체의 인터페이스에 스며들어 캡슐화의 원칙이 무너진다.

## 데이터 중심 설계

* **이 객체가 포함해야 하는 데이터는 무엇인가?** 라는 생각으로 접근하는 설계 방법이다.
* 객체의 종류를 저장하는 인스턴스 변수(movieType)와 인스턴스의 종류에 따라 배타적으로 사용될 인스턴스 변수(discountAmount, discountPercent)를 하나의 클래스 안에 함께 포함시키는 방식은 데이터 중심의 설계 안에서 흔히 볼 수 있는 패턴이다.
* 객체의 외부가 아니라 내부로 초점이 향하며 객체가 관리할 데이터의 세부 정보를 먼저 결정하므로, 객체의 구현이 이미 결정된 상태에서 다른 객체와 협력하기 위해 이미 구현된 객체의 인터페이스를 억지로 끼워맞출 수밖에 없다.

## 응집도

* 하나의 변경을 수용하기 위해 모듈 전체가 함께 변경된다면 응집도가 높은 것이고 모듈의 일부만 변경된다면 응집도가 낮은 것이다.
* 하나의 변경에 대해 하나의 모듈만 변경된다면 응집도가 높은 것이고, 다수의 모듈이 함께 변경돼야 한다면 응집도가 낮은 것이다.
* 응집도가 높을수록 변경의 대상과 범위가 명확해지기 때문에 코드를 변경하기 쉬워진다.

## 결합도

* 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도로 측정할 수 있다.
* 결합도가 높으면 높을수록 함께 변경해야 하는 모듈의 수가 늘어나기 때문에 변경하기가 어려워진다.

## 데이터 중심 설계의 문제

* getter, setter에 의존하여 내부 상태를 드러내는 메서드를 추가하면 내부 구현이 외부로 노출되므로 캡슐화를 위반한다.
* 내부 데이터의 타입이 변경되는 경우 메서드의 반환 타입도 변경해야 하므로 변경 지점이 많아진다.
* 객체에게 의미 있는 메서드는 **객체가 책임져야 하는 무언가를 수행하는 메서드**다.
* 객체는 단순한 데이터 제공자가 아니다. 객체 내부에 저장되는 데이터보다 **객체가 협력에 참여하면서 수행할 책임을 정의하는 오퍼레이션이 더 중요**하다.
