Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

오잉의 블랙잭이노라 구경하노라 #12

Open
wants to merge 17 commits into
base: hanueleee
Choose a base branch
from

Conversation

hanueleee
Copy link

No description provided.

hanueleee and others added 15 commits March 8, 2023 21:13
* docs: 기능 목록 작성

* feat: 카드 숫자를 보고 점수를 반환하는 기능 구현

* docs: 추가 예외 사항 작성

* feat: 52장의 카드를 생성하는 기능 구현

* feat: 카드 뽑기 기능 구현

* feat: 초기 카드 2장을 지급받는 기능 구현

* feat: 플레이어의 카드 뽑기 기능 테스트

* feat: 플레이어 이름이 '딜러'이면 예외가 발생하는 기능 구현

* refactor: Player 카드 뽑기 테스트를 Challenger 테스트로 이동

* refactor: HoldingCards를 만들어 일급 컬렉션으로 객체 분리

* docs: 기능 목록 업데이트

* feat: 가진 카드의 합을 반환하는 기능 구현

* feat: challenger의 카드의 합이 21이 넘어가는지 확인하는 기능 구현

* refactor: 카드 뽑기 테스트를 Player 테스트로 이동

* feat: dealer의 카드의 합이 16이 넘어가는지 확인하는 기능 구현

* feat: 중복된 이름 예외 처리 기능 구현

* feat: 플레이어 이름 입력 기능 구현

* refactor: 초기 카드 세팅 메소드 파라미터 형식 변경

* feat: 도전자, 딜러 구분해주는 기능 구현

* feat: 초기 카드 지급 상태 출력 기능 구현

* feat: 카드 추가 뽑기 입력 기능 구현

* feat: 카드를 더 받지 않으면 턴이 끝나는 기능 구현

* feat: 카드를 더 받지 않으면 턴이 끝나는 기능 구현

* feat: 최종 카드 상태 출력 기능 구현

* feat: ace를 고려한 카드 합계 계산 로직 구현

* docs: 기능 목록에 Result 객체의 역할 추가

* feat: 플레이어들의 최종 승패 여부 계산하는 기능 구현

* feat: 최종 승패 출력 기능 구현

* feat: 더 이상 뽑을 카드가 없을 경우 카드 덱이 비어있다는 예외 발생 기능 구현

* refactor: indent 2인 메소드 indent 1로 줄이기

* refactor: 출력 줄바꿈 수정

* refactor: inline이 필요해보이는 부분 inline으로 수정

* refactor: 출력 줄바꿈 수정

* refactor: Dto 내부 변환 로직을 controller로 이동 (Dto 내부 단순화)

* refactor: enum인 Number의 명칭을 Symbol로 변경

* refactor: CardDeck의 create메소드에 flatMap 적용

* refactor: 승패 판단 로직을 Dealer로 이동

* refactor: 카드 합 계산 로직 수정

* refactor: instanceof 대신 abstract method 사용

* refactor: 도메인에 의존하는 뷰 속 매직넘버 처리

* refactor: 도메인에 의존하는 문자열 처리

* refactor: 테스트 추가 및 수정

* refactor: CardDeck을 List에서 Deque으로 변경
Copy link
Member

@greeng00se greeng00se left a comment

Choose a reason for hiding this comment

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

오잉의 블랙잭 구경했도다.

List<Challenger> challengers = players.getChallengers();
List<Money> betAmounts = new ArrayList<>();
challengers.stream()
.forEach(challenger -> betEachPlayer(challenger, betAmounts));
Copy link
Member

Choose a reason for hiding this comment

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

stream보다 for-each가 가독성이 더 좋을 것 같은데 어떻게 생각하시나요?

for (Challenger challenger: players.getChallengers()) {
    betEachPlayer(challenger, betAmounts));
}

Copy link
Author

@hanueleee hanueleee Mar 12, 2023

Choose a reason for hiding this comment

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

리뷰어께서 stream 연습삼아 만들어보라고 하셔서 수정했던 부분임미다 ,, 🦹‍♂️
근데 저도 개인적으로 for-each 가 더 가독성이 좋을 것 같다고 생각합니당

Comment on lines 10 to 11
public static final Money ZERO = new Money(0);
private final int value;
Copy link
Member

Choose a reason for hiding this comment

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

상수와 필드는 한 칸 부탁드립니다

Copy link
Member

Choose a reason for hiding this comment

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

추가로 static 변수의 경우에도 public 먼저 작성하는게 우테코 컨벤션입니다

Copy link
Author

Choose a reason for hiding this comment

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

궁금한 점
public static final Money ZERO = new Money(0); 얘도 상수라고 보나요??

Copy link
Member

Choose a reason for hiding this comment

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

상수라고 말했지만, static 필드와 인스턴스 필드를 한 칸 구분하면 될 것 같습니다!

Comment on lines 41 to 59
public int getValue() {
return value;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Money money = (Money) o;
return value == money.value;
}

@Override
public int hashCode() {
return Objects.hash(value);
Copy link
Member

Choose a reason for hiding this comment

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

소소하지만 getter의 경우 equals & hashcode, toString 밑으로 위치하는게 컨벤션으로 알고 있습니다

Copy link
Author

Choose a reason for hiding this comment

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

아하 getter는 언제나 최하위에 위치해야한다는??
궁금한 점 : equals&hashcode, toString 말고 그냥 오버라이드한 함수들이어도 getter는 그 밑에 위치해야하나여??

Copy link
Member

Choose a reason for hiding this comment

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

넵 맞습니다!

Comment on lines 7 to 9
public static final String NAME = "딜러";

public static final int MAXIMUM_POINT = 16;
Copy link
Member

Choose a reason for hiding this comment

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

붙이는게 깔끔해보이네요

Copy link
Author

Choose a reason for hiding this comment

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

매의 눈 허브 🦅👀

Comment on lines 31 to 39
private Result resultWhenDealerIsBlackJack(Player challenger) {
if (challenger.isBust()) {
return Result.LOSE;
}
if (challenger.isBlackJack()) {
return Result.DRAW;
}
return Result.LOSE;
}
Copy link
Member

Choose a reason for hiding this comment

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

비교 로직이 깔끔해서 좋은 것 같습니다.

if (challenger.isBlackJack()) {
    return Result.DRAW;
}
return Result.LOSE;

로 개선할 수 있을 것 같습니다.

Copy link
Author

Choose a reason for hiding this comment

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

충격! 이걸 왜 놓쳤을까요 감사합니다

}

public static int inputPlayerBetMoney(String name) {
System.out.println(name+ REQUEST_PLAYER_BET_MONEY);
Copy link
Member

Choose a reason for hiding this comment

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

name + REQUEST_PLAYER_BET_MONEY
IntelliJ action on save 설정해는건 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

ㅎㅎ 감삼다

Comment on lines 43 to 55
public boolean isBust() {
if (status == Status.BUST) {
return true;
}
return false;
}

public boolean isBlackJack() {
if (status == Status.BLACKJACK) {
return true;
}
return false;
}
Copy link
Member

Choose a reason for hiding this comment

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

return status == Status.BUST

아래도 동일하게 개선할 수 있을 것 같아요 👍

Copy link
Author

Choose a reason for hiding this comment

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

감사합니다 허브좌

Copy link

@woo-chang woo-chang 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 +151 to +156
private PlayerStatusDto makePlayerStatusDto(Player player) {
String playerName = player.getName();
List<Card> inputCards = player.getHoldingCards().getCards();
int playerPoint = player.getTotalPoint();
return new PlayerStatusDto(playerName, makeCardInfo(inputCards), playerPoint);
}

Choose a reason for hiding this comment

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

dto로 해당 역할을 넘길 수 있을 것 같습니다!

.filter(player -> !player.isDealer())
.map(player -> (Challenger) player)
.collect(Collectors.toList());
return new ArrayList<>(challengers);

Choose a reason for hiding this comment

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

challengers 자체로 새로운 리스트가 만들어져서 new ArrayList<>로 다시 감쌀 필요가 없지 않을까요? 🤔

Copy link
Author

@hanueleee hanueleee Mar 13, 2023

Choose a reason for hiding this comment

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

ㅎㅎㅎ 제 리뷰어님이랑 똑같은 지적.. 역시 날카로운 다즐.. 감삼당
Collectors.toList()는 이미 안에서 자체적으로 방어적 복사를 해준다고 하네요!!

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

@@ -0,0 +1,10 @@
package blackjack.exception;

public class CustomException extends RuntimeException {

Choose a reason for hiding this comment

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

커스텀 예외를 잘 활용하시는 것 같아요 👍

Copy link
Author

Choose a reason for hiding this comment

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

<

Copy link
Collaborator

@shin-mallang shin-mallang left a comment

Choose a reason for hiding this comment

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

good


private void bet(Players players) {
List<Challenger> challengers = players.getChallengers();
List<Money> betAmounts = new ArrayList<>();
Copy link
Collaborator

Choose a reason for hiding this comment

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

List 말고 Map으로 관리하는건 어떻게 생각하세요?


private PlayerStatusDto makeDealerStatus() {
Player dealer = blackJackGame.getDealer();
return makePlayerStatusDto(dealer);
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기에 makePlayerStatusDto가 있는것보다는, PlayerStatusDto.from() 가 더 좋지 않을까요?
컨트롤러에 있으면 메서드가 너무 많아져서 복잡해지는거같아요

List<Challenger> challengers = blackJackGame.getChallengers();
return challengers.stream()
.map(challenger -> makePlayerStatusDto(challenger))
.collect(Collectors.toUnmodifiableList());
Copy link
Collaborator

Choose a reason for hiding this comment

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

굳이 toUnmodifiableList로 하신 이유가 있나요

}
}

private void inputChoice(Player player) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

입력만 받는 줄 알았는데, hit까지 하네요?
예상하지 못했는데 inputAndHit등으로 바꾸는건 어떨까요?

}

private void takeAllChallengersTurn() {
for (Player player : blackJackGame.getChallengers()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

blackJackGame의 자율성을 침해하는 것 같아요

this.betAmounts = betAmounts;
}

public static BlackJackGame from(Players players, List<Money> betAmounts) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

CardDeck을 생성자에서 받지 않고, 내부에서 생성해주는 이유가 있나요?

Choose a reason for hiding this comment

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

from인데 왜 2개?

}
}

public Money calculateRevenue(Result result) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Money는 돈에만 관련된 역할을 하는데, 수익이라는 개념이 들어가면, 그냥 Money로는 도메인 모델을 표현하는 것이 불충분하다고 생각하는데, 어떻게 생각하시나요?

}

private void validateName(String name) {
if (Dealer.NAME.equals(name)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

참가자의 이름이 딜러면 안되나요?
제 아들 이름 신딜러로 지을 생각이었는데,
벌써부터 차별당하네요?

Choose a reason for hiding this comment

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

논란

}

public static Players from(List<String> names) {
validateDuplicatedNames(names);
Copy link
Collaborator

Choose a reason for hiding this comment

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

동명이인은 게임에 참여할수 없나요? 왜죠???

@@ -0,0 +1,10 @@
package blackjack.exception;

public class CustomException extends RuntimeException {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이름에 Custom이 들어갈 필요가 있을까요?
차라리 BlackjackGameException이 더 좋을 것 같아요
너무 의미없는 네이밍 같습니다.

@greeng00se greeng00se self-requested a review March 13, 2023 11:13
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.

5 participants