> For the complete documentation index, see [llms.txt](https://incheol-jung.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://incheol-jung.gitbook.io/docs/study/object/2020-03-10-object-chap8.md).

# 8장 의존성 관리하기

잘 설계된 객체지향 애플리케이션은 **작고 응집도 높은 객체**들로 구성된다. 작고 응집도 높은 객체란 책임의 초점이 명확하고 **한 가지 일만 잘하는 객체**를 의미한다.

협력을 위해서는 의존성이 필요하지만 **과도한 의존성은 애플리케이션을 수정하기 어렵게 만든다.** 객체지향 설계의 핵심은 협력을 위해 필요한 의존성은 유지하면서도 변경을 방해하는 의존성은 제거하는데 있다.

## 의존성 이해하기

### 변경과 의존성

어떤 객체가 협력하기 위해 다른 객체를 필요로 할때 두 객체 사이에 **의존성**이 존재하게 된다. 의존성은 **실행 시점**과 **구현 시점**에 서로 다른 의미를 가진다.

의존성은 전이될 수 있기 때문에 의존성의 종류를 **직접 의존성**과 **간접 의존성**으로 나누기도 한다. 직접 의존성이란 말 그대로 한 요소가 다른 요소에 직접 의존하는 경우를 가리킨다. 간접 의존성이란 직접적인 관계는 존재하지 않지만 의존성 전이에 의해 영향이 전파되는 경우를 가리킨다.

```java
// 직접 의존성
Class Movie {
    private AmountDiscountPolicy amountDiscountPolicy 
        = new AmountDiscountPolicy();
    ...
}

// 간접 의존성
class Movie {
    private DiscountPolicy discountPolicy;
    
    Movie(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }
    ...
}
```

### 컨텍스트 독립성

클래스는 자신과 협력할 객체의 **구체적인 클래스**에 대해 알아서는 안된다. 구체적인 클래스를 알면 알수록 그 클래스가 사용되는 **특정한 문맥에 강하게 결합**되기 때문이다.

클래스가 사용될 특정한 문맥에 대해 최소한의 가정만으로 이뤄져 있다면 다른 문맥에서 재사용하기가 더 수월해진다. 이를 **컨텍스트 독립성**이라고 부른다.

시스템을 구성하는 객체가 컨텍스트 독립적이라면 해당 시스템은 변경하기 쉽다. 여기서 컨텍스트 독립적이라는 말은 각 객체가 해당 객체를 실행하는 시스템에 관해 아무것도 알지 못한다는 의미다.

## 유연한 설계

### 의존성과 결합도

다른 환경에서 **재사용**하기 위해 내부 구현을 변경하게 만드는 모든 의존성은 바람직하지 않은 의존성이다. 이를 다른 용어로 **결합도**로 일컫는다. 의존성이 바람직할 때 **느슨한 결합도** 또는 **약한 결합도**를 가진다고 말한다. 반대로 두 요소 사이의 의존성이 바람직하지 못할 때 **단단한 결합도** 또는 **강한 결합도**를 가진다고 말한다.

### 자식이 결합을 낳는다

결합도의 정도는 한 요소가 자신이 의존하고 있는 다른 요소에 대해 알고 있는 **정보의 양으로 결정**된다. 한 요소가 다른 요소에 대해 **더 많은 정보를 알고 있을수록 두 요소는 강하게 결합된다.** 서로에 대해 알고 있는 지식의 양이 결합도를 결정한다.

결합도를 느슨하게 만들기 위해서는 협력하는 대상에 대해 필요한 정보 외에는 **최대한 감추는 것**이 중요하다. 그것이 바로 **추상화**다.

### 추상화에 의존하라

추상화란 어떤 양상, 세부사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 **복잡도**를 극복하는 방법이다.

일반적으로 추상화와 결합도의 관점에서 의존 대상을 다음과 같이 구분하는 것이 유용하다. 목록에서 아래쪽으로 갈수록 클라이언트가 알아야 하는 지식의 양이 적어지기 때문에 결합도가 느슨해진다.

* 구체 클래스 의존성 -> 추상 클래스 의존성 -> 인터페이스 의존성

### new는 해롭다

결합도 측면에서 new가 해로운 이유는 크게 두 가지다.

* new 연산자를 사용하기 위해서는 **구체 클래스의 이름을 직접 기술**해야 한다. 따라서 new를 사용하는 클라이언트는 추상화가 아닌 구체 클래스에 의존할 수밖에 없기 때문에 결합도가 높아진다.
* **new 연산자는 생성하려는 구체 클래스뿐만 아니라 어떤 인자를 이용해 클래스의 생성자를 호출해야 하는지도 알아야 한다.** 따라서 new를 사용하면 클라이언트가 알아야 하는 **지식의 양**이 늘어나기 때문에 결합도가 높아진다.

훌륭한 객체지향 설계란 객체가 **어떻게 하는지**를 표현하는 것이 아니라 **객체들의 조합**을 선언적으로 표현함으로써 객체들이 무엇을 하는지를 표현하는 설계다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://incheol-jung.gitbook.io/docs/study/object/2020-03-10-object-chap8.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
