# 헤드 퍼스트 디자인 패턴

### Chapter 1

부모 클래스와 자식 클래스 두 분류로만 나눠버리면,\
나중에 자식이 많아졌을 때 행동을 바꾸기가 어렵다.\
override나 interface를 사용하면 구현을 조금 바꿀 때 일일이 찾아가서 다 바꿔줘야 하기 때문이다.

> 디자인 원칙\
> 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분과 분리하여 캡슐화한다.

클래스(인터페이스)에서 변화하는 행동들을 골라서 변화의 종류들을 인터페이스로 묶어버리고,\
클래스에선 그 인터페이스 아래에 있는 행동의 클래스들을 가져오면 코드가 좀 더 유연해진다.

> 디자인 원칙\
> 상속보다는 구성을 활용한다.

구성(composition) : 두 클래스를 합치는 것

### Chapter 2

옵저버 패턴

* 신문사와 구독자로 이루어지는 신문 구독 서비스
* 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고, 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의

Subject 인터페이스 : 객체에서 옵저버로 등록하거나, 옵저버 목록에서 탈퇴하고 싶을 땐 이 인터페이스에 있는 메소드를 사용한다.\
Observer 인터페이스 : 옵저버가 되고 싶은 객체는 반드시 Observer 인터페이스를 구현해야 한다. 이 인터페이스에는 주제의 상태가 바뀌었을 때 호출되는 update() 메소드밖에 없다.

느슨한 결합 : 객체들이 상호작용할 수는 있지만, 서로를 잘 모르는 관계. 이를 활용하면 코드의 유연성이 좋아진다.

> 디자인 원칙\
> 상호작용하는 객체 사이에는 가능하면 느슨한 결합을 사용해야 한다.

주제가 옵저버에게 상태를 알리는 푸시보다\
옵저버가 주제로부터 상태를 끌어오는 풀이 대체로 더 좋다.\
observer의 update()에 매개변수를 없애고,\
각 클래스마다 필요한 데이터만 가져가도록 getter를 써놓으면 된다.

### Chapter 3 \~ 6

데코레이터 패턴 : 좀 별로인듯. 객체를 파고파고 들어가야하는게 마음에 들지 않는다. 구현도 어렵고 사용도 어렵고... 어쩔 수 없이 써야할 때 쓰는 패턴인듯.

팩토리 패턴 : 간단한 팩토리 패턴은 그냥 캡슐화한다는거고, 팩토리 메소드 패턴은 거기에 상속으로 경우 나눈다는거. 추상 클래스 패턴은 거기에 또 composition 추가.

의존성 역전 : 종류별로 다 쪼개지 말고 부모 클래스로 묶어라. 부모 클래스에 의존하게 되는걸 의존성 역전이라고 표현한듯. 이름이 별로 마음에 들진 않는다. 결국 여러 개에 의존하던 걸 부모 클래스 하나에 의존하게 되니까 '원래'의 의존성 방향은 그대로고 역전된 방향으로의 의존성이 추가되는 건데 역전이라고만 하면 직관적이지도 않고 헷갈리는듯.

싱글톤 패턴 : 전역 변수 및 static 메서드를 인스턴스화하여 좀 더 유연하게 만든다.

커맨드 패턴 : 특정 경우마다 if문으로 나누는게 아니라 execute() 메서드를 가진 명령 인스턴스를 만든 뒤 그 명령을 처리하는 인스턴스에 보낸다. 인스턴스 대신 함수 객체로 composition할 수도 있다.

### Chapter 7 \~ 9

어댑터 패턴 : 인터페이스 바꿔치기. 형식 맞춰주기 위해 메서드를 택갈이한다.\
퍼사드 패턴 : 여러 클래스 명령 묶은 메서드들 담은 클래스

템플릿 메소드 패턴 : 여러 메서드를 묶은 메서드 중에 일부는 추상 메서드로 둬서 서브 클래스에 따라 다르게 작동하도록 한다. 행동이 더 분화하면 hook라는 걸로 if문 분기 처리할 수도 있다. 추상 메소드 구현 일일이 해야해서 좀 번거로운 상황이 많이 나오긴 할듯.

반복자 패턴 : 여러 컬렉션 자료형에 접근할 때 hasnext(), next() 이런 걸로 추상화

컴포지트 패턴 : 트리 구조로 객체를 구성한다. 자식 있는 노드랑 없는 노드를 똑같이 다룬다. 필요하면 자식 순회하면서 자식 동작들 실행할 수도 있고, 자식 추가하거나 편집할 수도 있다. 자식에 아무 의미 없는 메소드 생길수도 있다.

### Chapter 10, 11

상태 패턴

* 상태 전환 코드를 상태 클래스에 넣으면 상태 클래스들 사이에 의존성 생길 수 있으니 Context 객체에서 해결하는 방법 있다
* 상태를 공유할 땐 각 상태를 정적 인스턴스 변수에 할당한다

프록시 패턴 : 어떤 객체가 다른 객체의 접근 통제. stub(클라측 메서드) 호출할 땐 오류 예외를 꼭 달아줘라.


---

# Agent Instructions: 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:

```
GET https://lazyartisan.gitbook.io/note/main-page/books/undefined-4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
