Skip to content

[🚀 사이클2 - 미션 (블랙잭 베팅)] 와이제리 미션 제출합니다.#1136

Merged
verus-j merged 33 commits intowoowacourse:yj9107vfrom
yj9107v:step2
Mar 20, 2026
Merged

[🚀 사이클2 - 미션 (블랙잭 베팅)] 와이제리 미션 제출합니다.#1136
verus-j merged 33 commits intowoowacourse:yj9107vfrom
yj9107v:step2

Conversation

@yj9107v
Copy link
Copy Markdown

@yj9107v yj9107v commented Mar 17, 2026

체크 리스트

  • 미션의 필수 요구사항을 모두 구현했나요?
  • Gradle test를 실행했을 때, 모든 테스트가 정상적으로 통과했나요?
  • 애플리케이션이 정상적으로 실행되나요?

어떤 부분에 집중하여 리뷰해야 할까요?

1️⃣ Controller의 책임은 어디까지라고 보시나요?

사이클1 때에도 Controller 자체가 많이 복잡했습니다. 한눈에 파악하기 어려워, 입력 생성, 출력, 플레이어/딜러 진행 책임을 분리해 각각의 클래스로 관리하는 방향으로 책임 분리를 해보려고 합니다.

MVC 패턴을 더 잘 적용하면서도 관리하기 쉬운 구조로 만들려면, 이러한 방향으로 분리하는 것이 괜찮을지 궁금합니다.


2️⃣ 비즈니스 규칙에서 도메인이 책임져야 할 부분과 Controller, View가 책임져야 할 부분의 기준이 궁금합니다.

구현을 하면서 늘 가장 고민되는 부분 중 하나는, 어떤 코드를 도메인에 두어야 하는지입니다. 예를 들어 사이클 1 구현에서 딜러가 16 이하이면 카드를 추가로 받는 규칙이 있었는데, 이 경우 Controller에서 while문을 사용해 dealer.draw()를 호출해야 하는지, 아니면 Dealer 내부에 16 이하일 때 카드를 추가로 받는 규칙을 구현해야 하는지 고민이 되었습니다.

또 다른 예시로는, 추가 카드를 y, n으로 입력받아 플레이어에게 카드를 추가하는 부분이 있습니다. 입력받은 y를 플레이어에게 전달해 Player 내부에서 y, n에 대한 판단을 하고 카드를 추가해야 하는지, 아니면 Controller에서 그 역할을 담당해야 하는지도 고민되었습니다.

저는 두 예시 모두 출력 흐름과 관련이 있다고 생각해 Controller에서 구현했는데, 이것이 명확한 기준이라고 느껴지지는 않았습니다. 이 부분에 대해 리뷰어님께서는 어떤 기준으로 판단하시는지도 궁금합니다.


3️⃣ 기능 추가와 관련해 질문드리고 싶습니다!

이번 사이클2에서는 블랙잭 배팅 기능이 추가되었습니다. 배팅 기능을 넣기 위해 두 가지 방법을 고민했습니다.

첫 번째는 플레이어와 딜러가 필드로 배팅 금액을 가지도록 하는 방식입니다. 플레이어가 자신의 배팅 금액을 직접 가지고 있는 것도 같은 책임 안에 포함될 수 있다고 생각했습니다.

두 번째는 이번 프로그래밍 요구사항 중 하나인 “인스턴스 변수 3개를 넘지 않는다”는 규칙을 지키기 위해, 플레이어와 배팅 금액을 필드로 가지는 PlayerBet 클래스를 만들어 사용하는 방식입니다. 다만 두 번째 방법은 기존 클래스를 수정하기보다 새로운 클래스를 생성해 함께 사용해야 하는 부분이 많아 보였습니다.

위 두 가지 방법의 단점은, 첫 번째는 책임이 많아져 클래스가 무거워질 수 있다는 점이고, 두 번째는 책임이 가벼워지는 대신 기능이 여러 곳으로 퍼질 수 있다는 점이라고 생각했습니다.

저는 두 번째 방법을 선택했고, 앞으로 구현하면서 최대한 기능을 분리해 보려고 합니다. PlayerBet과 같이 클래스를 구성한 방식에 대해 리뷰어님께서는 어떻게 생각하시는지 궁금합니다.


yj9107v added 30 commits March 14, 2026 14:49
- 객체지향적인 코드를 위해 초기 핸드 사이즈를 Deck으로 이동
- Controller에서 Dealer, Player의 초기 드로우 된 카드 사이즈를 이용해 사용
- List와 연관된 assertThat containsExactly() 활용하여 플레이어의 승/무/패/버스트 여부를 한 번에 테스트
- 플레이어, 딜러 버스트인 경우 테스트 추가
- 딜러의 승/무/패 횟수 테스트 추가
- Cards -> Deck 클래스 이름 수정
- 테스트에 맞는 설명 수정DisplayName
- 정수형 반환 전에 입력받은 문자열이 숫자 패턴에 맞는지 검증
- 배팅 금액인 BettingAmount 클래스 추가
- 플레이어, 배팅 금액을 보유한PlayerBet 클래스 추가
- PlayerBet의 일급컬렉션 PlayersBet 클래스 추가
- int, long, double보다 정확한 소수 계산을 위한 BigDecimal 사용
- 금액을 잃는 경우인 applyLoseAmount() 추가
@yj9107v yj9107v changed the base branch from main to yj9107v March 17, 2026 06:40
Comment on lines +32 to +34
public BigDecimal value() {
return amount;
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오차 없이 정확하게 계산해야 하는 값에는 BigDecimal을 사용하는 것이 좋다고 하여 적용해 보았습니다.

이와 관련해 궁금한 점이 있습니다. value()처럼 값 객체를 반환하는 메서드에서 반환값을 BigDecimal 그대로 반환하지 않고, String으로 변환해 반환하는 경우 이것도 뷰와 연관된 책임을 도메인이 가지게 되는 것인지 궁금합니다.

Copy link
Copy Markdown

@verus-j verus-j Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쉽게 사용자에게 보여줄 정보의 양식이 변경될 경우 도메인이 같이 변경되면 뷰와 연관된 책임을 도메인이 가진다고 볼 수 있겠네요. BigDecimal을 그대로 반환하지 않고 String으로 변환했을 때, 베팅 금액과 관련된 뷰가 변경되면 어디가 변경될 지 고민해보면 답을 찾을 수 있을 것 같아요~

Copy link
Copy Markdown

@verus-j verus-j left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 와이제리~
테스트 코드와 관련된 리뷰 먼저 드립니다. 테스트 코드 쪽에서 주석을 사용해 설명한 곳이 많은데, 테스트 코드를 개선하여 주석을 어떻게 제거할 수 있을지 고민해보면 좋을 것 같아요~

Comment on lines +89 to +104
private List<Card> createCards(String input) {
if (input.equals("블랙잭")) {
return List.of(Card.of(Rank.ACE, Suit.SPADE), Card.of(Rank.J, Suit.HEART)); // 블랙잭
}
if (input.equals("승리")) {
return List.of(Card.of(Rank.J, Suit.SPADE), Card.of(Rank.Q, Suit.HEART),
Card.of(Rank.ACE, Suit.DIAMOND)); // 21
}
if (input.equals("무승부")) {
return List.of(Card.of(Rank.TEN, Suit.DIAMOND), Card.of(Rank.TEN, Suit.CLOVER)); // 20
}
if (input.equals("패배")) {
return List.of(Card.of(Rank.TEN, Suit.HEART), Card.of(Rank.SEVEN, Suit.CLOVER)); // 17
}
return List.of(Card.of(Rank.J, Suit.SPADE), Card.of(Rank.Q, Suit.CLOVER), Card.of(Rank.K, Suit.HEART)); // 버스트
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개별 케이스를 상수 List로 선언하는 것도 좋은 방향이 될 것 같습니다. 주석도 필요할지 다시 한번 고민해보면 좋을 것 같아요~

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개별 케이스를 상수 List로 선언하는 것도 좋은 방향이 될 것 같습니다. 주석도 필요할지 다시 한번 고민해보면 좋을 것 같아요~

상수 List로 선언하면 주석 변수명으로 주석 또한 없앨 수 있겠네요.
BlackjackResult와 비슷한 방식으로 상수 List 선언하여 수정했습니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개별 케이스를 상수 List로 선언하는 것도 좋은 방향이 될 것 같습니다. 주석도 필요할지 다시 한번 고민해보면 좋을 것 같아요~

추가로 궁금한 점이 있습니다.
테스트 코드에서 winCards, drawCards처럼 다른 테스트에서도 함께 사용하는 상수들은 Fixture로 공통 관리하는 방향이 더 나아 보이는데, 공통되는 부분이 3곳 이상이라 Fixture로 분리해도 괜찮을지 리뷰어님의 의견이 궁금합니다.

Copy link
Copy Markdown

@verus-j verus-j Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixture로 분리해서 사용하는 것도 좋아보입니다. 다음에는 비슷한 상황에 적용해보면 좋을 것 같아요~

Comment thread src/test/java/domain/BlackjackBettingCalculatorTest.java Outdated
Comment thread src/test/java/domain/BlackjackResultTest.java
Comment thread src/test/java/domain/DealerTest.java Outdated
Copy link
Copy Markdown

@verus-j verus-j left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 와이제리~
미션 진행하시느라 고생하셨습니다. 테스트 케이스 피드백을 이전에 드렸는데, 당시에 생각했던 프로덕션 코드의 문제도 같이 잘 수정해주셔서 더 이상 피드백을 남길 게 없는 것 같아요. 질문의 답변은 오늘 중으로 슬랙에 남겨놓겠습니다! 남은 우테코 일정도 화이팅입니다~

Comment on lines +14 to +16
public void addInitialCards(List<Card> cards) {
cards.forEach(this::addCard);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

초기에 카드 여러장을 받기위해서 만들었지만, Hand의 addInitialCards 메서드만 봤을 때는 카드 리스트를 추가하는걸로 보입니다. 메서드 명을 범용적인 addCards로 수정하는게 더 좋아보여요~

import java.util.ArrayList;
import java.util.List;

public class Hand {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조합을 사용해 중복된 코드를 정리하셨네요! 잘하셨습니다~

@verus-j verus-j merged commit 22c54e6 into woowacourse:yj9107v Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants