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
Binary file added .DS_Store
Binary file not shown.
File renamed without changes.
8 changes: 8 additions & 0 deletions jihun/reservation/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions jihun/reservation/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions jihun/reservation/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 107 additions & 0 deletions jihun/reservation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
> 항상 생각하면서 책을 읽자!
>

# 01. 객체, 설계

## 티켓 판매 애플리케이션 구현하기

### ✅ 읽기 전에 생각 정리

⚠️ 잘못된 접근 ⚠️

- 책임을 먼저 생각해버린 잘못된 접근 → 책임을 먼저 생각하니까 객체가 잘 생각나지 않는다;

이벤트에 당첨o → 초대장을 티켓으로 교환

이벤트에 당첨x → 티켓 구매

우선 무엇을 생각해야 할까?

역할? 책임? 협력? // 상태? 행동? 식별자?

전자는 객체지향을 표현하는 3가지 용어이고, 후자는 객체를 표현하는 3가지 용어이다.

저자는 객체가 어떤 행동을 가지고, 어떤 책임을 가지는지 먼저 생각하고, 그 다음 협력을 생각하라고 하였다. 인정하는가?

그렇다면 행동과 책임을 생각하며 각각의 객체들을 정의해보자.

행동…책임…행동…책임…행동…책임

- 생각이 잘 나지 않는다. 문제의 키워드를 뽑아보자. `이벤트`, `초대장`, `티켓` 이렇게 3가지가 눈에 띈다.
- 그럼 우선 `이벤트` 부터 생각해보자.
- 이벤트는 어떤 행동과 책임을 가지고 있을까?
- 초대장이 적절한 초대장인지 확인하는 `행동`을 할 수 있네?
- 그럼 얘는 초대장을 확인하는 `책임`을 가지고 있겠구나.
- 그럼 초대장을 확인하기 위해 협력이 필요해. `초대장`과 `협력`을 해보자.
- 이벤트는 초대장과 협력을 통해서 적절한 초대장인지 확인이 끝났다.
- 그렇다면 이벤트는 티켓으로 교환해주어야 한다. 여기서 새로운 객체의 등장이 필요하다고 생각한다.
- 왜? 이벤트의 역할은 초대장의 진위 여부만 확인하는 책임으로 끝인것이다.
- 자, 그러면 티켓을 교환해주는 관리자 객체를 추가해보자.

- `관리자`는 돈 or 초대장을 받고 티켓으로 교환해주는 역할 및 책임을 가지고 있다고 보면 되겠다.
- 돈을 받는다 → 그러면 가격에 맞게 티켓 수량을 계산해줘야 한다. 이건 관리자의 책임이 아니다. 돈을 받으면 티켓 수량을 반환해주는 새로운 객체와 `협력`이 필요한 시점이다.
- 새로운 객체의 책임은 티켓 수량을 반환해주는 것 → `티켓 교환기`로 객체의 이름을 정의
- 초대장을 받는다 → 관리자는 초대장이 효력이 있는지 모른다. 따라서 `이벤트`에게 `협력`을 요청한다.

정리해보자

객체는 관리자, 초대장, 티켓, 이벤트, 티켓 교환기 이렇게 5개를 정했다.

- `관리자`
- 돈, 초대장에 대한 협력이 들어오면
- 티켓을 반환해주는 책임
- `티켓 교환기`
- 가격, 초대장에 대한 협력이 들어오면
- 티켓 수량을 반환해주는 책임
- `이벤트`
- 초대장에 대한 협력이 들어오면
- 진위 여부 확인하는 책임
- `티켓`
- 역할? 책임? 그냥 상태값만 가지고 있으면 될거같은데?
- `초대장`
- 역할? 책임? 그냥 상태값만 가지고 있으면 될거같은데?

음…찝찝하다~ 일단 책을 읽고 다시 돌아온다…


---

### ✅ 개선 코드 보기 전 생각 정리

1. 자율성 (Tell, Don’t Ask)
2. 결합도 (의존성)

우선 객체에 대한 선택을 잘 했는가 부터 살펴보자.

- Audience
- Bag
- Invitation
- Ticket
- TicketOffice
- TicketSeller
- Theater

→ 응~ 잘못했어~

### 큰 협력부터 생각해보자 → 메시지

[티켓을 판매하세요]

- ticketSeller → 티켓을 팔아야 하는 책임 → Audience 에게 → 뭐든 내놔! (협력 요청)
- Audience → 돈 or 초대장을 줘야하는 책임 생김 → 하지만 돈 or 초대장 둘 중 하나를 가지거나 둘 다 가질 수 있다. 따라서 이 둘을 관리할 또 다른 객체가 있으면 좋다. → bag 에게 → 나 뭐있니?? (협력 요청)
- bag → 초대장이나 돈을 가지고 있을 책임이 생김
- Audience 로 부터 뭐든 달라는 요청을 받으면
- 가방은 초대장과 돈을 확인 → 이때도 (협력 발생)
- 초대장아~ 내 초대장 적절하니??
- 티켓아~ 내 돈으로 널 살 수 있니??

- 이제 Audience 가 ticketSeller 한테 값을 반환하면
- ticketSeller 는 티켓을 반환해야 하는 데!! 티켓은 무한개가 아님 → 나 줄 수 있을 까?? 티켓아?? (협력 요청)
- 그럼 Ticket 은 갯수를 확인하고, 적절한 수량이면 빵 한조각 쥐어 주면서 퇴장

포인트는 데이터와 데이터를 사용하는 프로세스가 동일한 객체 안에 위치해야 객체지향 프로그래밍이다. (책임)

즉, 낮은 결합도! 높은 응집도!

> 완벽한 설계는 없다. 정답도 없다. 어느 정도 설계를 마쳤으면 코드로 구현을 해보자. 코드로 보면 설계가 잘못된 것을 알 것이고, 반복되다 보면 발전할 것이라고 믿어 의심치 않는다.
>
11 changes: 11 additions & 0 deletions jihun/reservation/reservation.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
15 changes: 15 additions & 0 deletions jihun/reservation/src/controller/TheaterController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package controller;

import view.InputView;

public class TheaterController {
//view 에서 관객에 대한 정보가 넘어옴
//해당 관객에 대한 처리를 판매자에게 넘김
//판매자가 최종적으로 티켓을 반환하면
//view 로 다시 넘김

public static void enter() {
int ticketCnt = InputView.enter();

}
}
13 changes: 13 additions & 0 deletions jihun/reservation/src/domain/Audience.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package domain;

public class Audience {
private final Bag bag;

public Audience(Bag bag) {
this.bag = bag;
}

public int buy(int tickets) {
return 0;
}
}
7 changes: 7 additions & 0 deletions jihun/reservation/src/domain/Bag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package domain;

public class Bag {
private int money;
private Invitation invitation;

}
4 changes: 4 additions & 0 deletions jihun/reservation/src/domain/Invitation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package domain;

public class Invitation {
}
13 changes: 13 additions & 0 deletions jihun/reservation/src/domain/Ticket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package domain;

public class Ticket {
private int amount = 100;

public int getTicket(int count) {
if(amount > count) {
//예외 발생
}
amount -= count;
return count;
}
}
8 changes: 8 additions & 0 deletions jihun/reservation/src/domain/TicketSeller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package domain;

public class TicketSeller {

public void sellTo() {

}
}
12 changes: 12 additions & 0 deletions jihun/reservation/src/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package view;

import java.util.Scanner;

public class InputView {
private static final Scanner scanner = new Scanner(System.in);
public static int enter() {
System.out.println("관람객이 입장합니다. 티켓을 판매하세요.");
System.out.print("티켓 구매 수량을 입력해주세요 : ");
return scanner.nextInt();
}
}