Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions book/3주차/이승건 3주차.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions book/객사오/1주차/1주차.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# 1주차
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
421 changes: 421 additions & 0 deletions book/오브젝트/1장/이승건_오브젝트_1장 객체, 설계 .md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# 3장 : 역할, 책임, 협력

> “객체지향에서 가장 중요한 것은 역할, 책임, 협력이다. 역할, 책임, 협력이 제자리를 찾지 못한 상태라면 응집도 높은 클래스와 중복 없는 상속 계층을 구현하더라도 의미없다.”
>

- **협력 →** 객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용
- **책임** → 객체가 협력에 참여하기 위해 수행하는 로직
- **역할** → 객체가 협력안에서 수행하는 책임들이 모여 객체가 수행하는 것

# ✅협력

```java
public class Screening {

public Money calculateFee(int audienceCount) {
return movie.calculateMovieFee(this).times(audienceCount);
}
```

- 위 코드에서처럼 **협력**은 하나의 객체(Screen)가 다른 객체(Movie)에게 도움을 요청할 때 시작된다.
- 객체는 다른 객체의 상세한 내부 구현에 직접 접근할 수 없기에(private으로 캡슐화를 했기에) 오직 메시지 전송을 통해서만 자신의 요청을 전달할 수 있다.

```java
public class Movie {
public Money calculateMovieFee(Screening screening) {
return fee.minus(discountPolicy.calculateDiscountAmount(screening));
}
}
```

- 메시지를 수신한 객체(Movie)는 메서드(`calculateMovieFee`)를 실행해 요청에 응답한다.
- 메시지를 수신한 객체는 메시지를 처리할 방법(로직)을 스스로 선택한다는 점이 중요하다. 외부 객체는 오직 메시지만 전송할 수 있다. → 이는 객체가 자율적인 존재라는 것을 뜻한다.
- 메시지를 수신한 객체(Movie)는 메시지를 처리하던 중에 직접 처리할 수 없는 정보나 행동이 필요한 경우 또 다른 객체(discountPolicy)에게 위처럼 도움을 요청할 수 있다.
- Screening이 Movie에게 처리를 위임하는 이유는 요금을 계산하는데 필요한 기본 요금과 할인 정책을 가장 잘 알고 있는 객체가 Movie이기 때문이다.

- 객체 사이의 협력을 설계할 때는 객체를 서로 분리된 인스턴스가 아닌 협력하는 파트너로 인식해야 한다. → 즉 Movie와 Screeening은 영화를 예매하는 협력에 참여한다.

- 🤓 : 캡슐화시 객체가 가질 수 있는 상태와 행동은 어떤 기준으로 결정해야하나?? 객체를 설계할 때 어떤 행동과 상태를 할당했다면 이유는 무엇인가?
- 객체의 행동을 결정하는 것은 객체가 참여하고 있는 **협력**이다.
- 협력은 객체가 필요한 이유와 객체가 수행하는 행동의 동기를 제공한다.

```java
public class Movie {
private Money fee;
private DiscountPolicy discountPolicy;

public Money calculateMovieFee(Screening screening) {
return fee.minus(discountPolicy.calculateDiscountAmount(screening));
}
}
```

- **상태(변수)**는 객체가 행동하는 데 필요한 정보에 의해 결정되고, **행동(메서드)**은 협력 안에서 객체가 처리할 메시지로 결정한다.
- Movie는 영화를 예매하기 위한 협력에 참여 하고있다.
- Movie가 기본 요금인 fee와 할인 정책인 discountPolicy라는 인스턴스 변수를 상태의 일부로 포함하는 이유는 요금 계산이라는 행동을 수행하는데 해당 상태가 필요하기 때문이다.

<aside>
😎 **협력**은 객체를 설계하는 데 필요한 일종의 문맥을 제공한다.

</aside>

# ✅책임

- 협력이 갖춰진 다음 할 행동은, 협력에 필요한 행동을 수행할 수 있는 적절한 객체를 찾는 것이다. 이 때 객체가 수행하는 행동을 **책임**이라고 부른다.

- 객체의 책임은 ‘하는 것’과 ‘아는 것’의 두가지 범주로 나누어 세분화된다.

![캡처.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/%25EC%25BA%25A1%25EC%25B2%2598.jpg)


- 하는 것
- Screening의 책임은 영화를 예매하는 것
- Movie의 책임은 요금을 계산하는 것
- 아는 것
- Screening은 `영화를 예매하기 위해` 자신이 상영할 영화를 알고 있어야 한다.
- Movie는 `요금을 계산하기 위해` 가격과 어떤 할인 정책이 적용됐는지도 알고 있어야 한다.

- 🤓 : 객체의 책임은 하나라는 SRP는, 하는 것과 아는 것을 한 세트로 치는 것이다.

- 위 예시를 보면 알 수 있듯이 객체는 자신이 맡은 책임을 수행하는 데 필요한 정보를 알고 있을 책임이 있다.
- 협력 안에서 객체에게 할당한 책임이 외부의 인터페이스(메서드)와 내부의 속성(변수)을 결정한다.

<aside>
😎 “객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에 할당하는 것”

</aside>

![객체지향 설계간에 적용해보는건 어떨까???](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/8.jpg)

객체지향 설계간에 적용해보는건 어떨까???

- 자율적인 객체를 만드는 가장 기본적인 방법은 책임을 수행하는 데 필요한 정보를 가장 잘 알고있는 전문가에게 그 책임을 할당하는 것이다. → **Information expert 패턴**
- 일상생활에서 문제가 생기면 누구에게 도움을 청하나?? 가장 전문가에게 청하지 않는가?? 이와 똑같다.

- **책임 주도 설계** → 위 같이 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식
1. 시스템이 사용자에게 제공하는 기능을 시스템이 담당할 하나의 책임으로 바라본다. 이게 **협력**이다.
1. ex) 시스템은 사용자에게 영화를 예매할 수 있게 해야해
2. 시스템 책임을 더 작은 책임으로 분할한다.
3. 분할 된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
1. 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요하면 이를 책임질 적절한 객체 또는 역할을 찾는다.
4. 2~3번을 반복한다.

- ex) 영화 예매 시스템을 예로 정보 전문가에게 책임을 할당하는 방법
1. 시스템은 사용자에게 영화를 예매하는 기능을 제공해야 해 → “예매해라” 라는 시스템의 책임으로 할당 → 책임을 할당한다는 것은 메시지의 이름을 결정하는 것과 같다. → “예매해라”라는 협력

![9.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/9.jpg)

2. “예매해라”라는 협력을 처리할 수 있는 객체를 선택해야 한다. → 예매에 관련 된 정보를 가장 많이 알고 있는 객체(정보 전문가)인 Screening에게 할당한다.

![10.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/10.jpg)

3. 예매하기 위해서는 가격을 계산 해야 하는데 Screening 힘으로는 못하기에, 외부 객체에게 가격 계산 요청 → “가격을 계산해라”라는 협력을 처리할 수 있는 객체를 선택

![11.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/11.jpg)

4. 2~3번을 반복한다.

- 책임을 할당할 때 고려해야 할 두 가지 요소
1. 메시지가 객체를 결정한다.
2. 행동이 상태를 결정한다.

### 메시지가 객체를 결정한다.

- 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 해야 하는 두 가지 이유
- ex) “예매해라”라는 메시지에 가장 알맞은 정보 전문가 객체를 선택
1. 객체가 최소한의 인터페이스를 가질 수 있게 된다.
1. 메시지를 수신하기 전까지 객체에 어떤 것도 추가 하지 않기에
2. 객체는 충분히 추상적인 인터페이스를 가질 수 있게 된다.
1. 메시지는 외부의 객체가 요청하는 무언가를 의미하기 때문에 메시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.

### 행동이 상태를 결정한다.

- 객체가 존재하는 이유는 협력에 참여하기 위해서이고, 객체는 따라서 협력에 필요한 행동을 제공해야 한다.

<aside>
😎 객체를 객체답게 만드는 것은 객체의 상태가 아니라 객체가 다른 객체에게 제공하는 행동이다.

항상 협력 관계 속에서 다른 객체에게 무엇을 제공해야 하고, 다른 객체로부터 무엇을 얻어야 하는지를 고민해야만 훌륭한 책임을 수확할 수 있다.

상태는 객체가 행동을 정상적으로 수행하기 위해 필요한 재료일 뿐이다.

</aside>

- 객체지향 초보자들은 먼저 객체에 필요한 상태가 무엇인지를 결정하고, 그 후에 상태에 필요한 행동을 결정한다.
- 이런 방식은 객체의 내부 구현이 객체의 퍼블릭 인터페이스에 노출되도록 만들기에 캡슐화를 저해한다.


# ✅역할

- 객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합을 **역할**이라고 부른다.
- 협력을 모델링할 때는 특정한 객체가 아니라 역할에게 책임을 할당한다고 생각하는 것이 좋다.

- 영화 예매 협력에서 “예매하라”라는 메시지를 처리하기 위한 과정은 사실은 두 독립적인 단계가 합쳐졌다.
1. 영화를 예매할 수 있는 적절한 역할이 무엇인가를 찾는다.
2. 역할을 수행할 객체로 Screening 인스턴스를 선택한다.

- 🤓 : 아니 굳이?? 그냥 **역할** 없이 메시지를 수행할 객체를 찾으면 안돼?? 설계가 한 단계 더 생기잖슴
- **상속**을 생각하면 왜 역할이 필요한지 알게 될 걸~!!
- 그냥 역할 없이 메시지를 수행할 객체를 찾는다고 가정하자.
- 예를 들어서 “할인 요금을 계산하라”라는 메시지를 Movie 객체가 보냈다고 치자. 그러면 메시지를 해결할 수 있는 객체를 찾을 거야. 이 때 해결할 수 있는 객체는 AmountDiscountPolicy랑 PercentDiscountPolicy 2개잖아. 그러면 두 종류의 객체가 참여하는 협력을 개별적으로 만들어줘야겠네?

![12.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/12.jpg)

- 이렇게 두 협력을 구현하면 AmountDiscountPolicy와 PercentDiscountPolicy의 코드가 대부분 중복하지 않겠니??
- 그렇기에 해결할 수 있는 객체가 아니라 “할인 요금을 계산하라”라는 메시지를 해결할 책임에 초점을 맞추고 봐야해!
- 그러면 AmountDiscountPolicy와 PercentDiscountPolicy 모두 할인 요금 계산이라는 동일한 책임을 수행하고있다는 것을 알 수 있지. 그러면 생각나는거 있지 않니?? **상속을 통한 추상화**
- 또한 **추상화**는 협력 안에서 두 종류의 객체를 교대로 바꿔 끼울 수 있는 일종의 **슬롯**으로 생각할 수 있지.
- 추상화 == 슬롯 == 역할

![13.JPG](3%E1%84%8C%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF,%20%E1%84%8E%E1%85%A2%E1%86%A8%E1%84%8B%E1%85%B5%E1%86%B7,%20%E1%84%92%E1%85%A7%E1%86%B8%E1%84%85%E1%85%A7%E1%86%A8%20ac70c50055b8409cbc305c2bd4b837ce/13.jpg)


- 🤓 : ㅇㅋㅇㅋ 알겠어. 그런데 만약 메시지를 해결할 수 있는 객체가 하나밖에 없는데도 굳이 역할이 필요해??
- 협력에 적합한 책임을 수행하는 대상이 한 종류라면 간단하게 역할이 아니라 객체로 간주하고, 위 같이 여러 객체들이 참여할 수 있다면 역할이라고 불러!!



- 실 설계간에는 아래와 같이 해보자
- 처음에 특정 시나리오에 대한 협력을 구상한다면 아마도 도메인 모델에 있는 개념들을 후보로 선택해서 직접 책임을 할당할 것이다.
- 이 때 다양한 시나리오를 설계로 옮기면서 협력을 지속적으로 정제하다 보면 두 개 이상의 협력이 거의 유사한 구조(같은 메시지를 응답할 수 있다는 것)를 보인다는 것을 발견할텐데 이 때 역할을 사용해보자!

- 역할의 가장 큰 장점은 설계의 구성 요소를 추상화할 수 있다는 것이다.

- 하나의 배역을 여러 배우가 연기할 수 있는 것처럼 동일한 역할을 수행하는 하나 이상의 객체들이 존재할 수 있다.
- 이것은 협력 관점에서 동일한 역할을 수행하는 객체들은 서로 대체 가능하다는 것을 의미한다. → **다형적**
- 또한 객체는 여러 협력에 참여하면서 다양한 역할을 수행할 수 있으나, 협력 안에서는 하나의 역할로 보여진다.

<aside>
😎 역할은 객체의 페르소나다.

</aside>
47 changes: 47 additions & 0 deletions d
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
commit 9592907c998f7ce9790af9e1e0080e3fd5f58d46 (HEAD -> master, origin/master, origin/HEAD)
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 21:10:03 2022 +0900

chores : 간격 수정

commit 0b6d57b14d7057d00fe42bfa73de14e136e080be
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 21:08:37 2022 +0900

add : 책 미션 진행 방법 내용 추가

commit 25cbb4c0d0aab09550d604b5f9e4c68c6ba51d82
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 20:59:03 2022 +0900

chores : README.md 레포 이름 수정

commit cf74f9ed9e47f4aac33c9cb50fbecb2e3ceeaa30
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 20:55:20 2022 +0900

add : 1주차 추가

commit 78d5e243925258900e844741ab31ed4f15117056
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 20:55:07 2022 +0900

add : 미션 제출 방법 추가

commit 3101420774f49668ab1dca3a01a879d03b08917d
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 20:22:56 2022 +0900

add : 숫자 야구 미션 추가

commit 1515a15dca160ff740abd300ee0520ee323daffe
Author: JeonginKim <47661695+mywnajsldkf@users.noreply.github.com>
Date: Sat Nov 19 20:16:03 2022 +0900

add : .gitignore 추가, README.md 작성

commit 46966f567b122b98eae019d698b5a0fb8767cbb7
Author: mywnajsldkf <mywnajsldkf@gmail.com>
Date: Thu Nov 17 09:48:39 2022 +0900

first commit