Conversation
- 생성자 호출시 인자를 통한 여행거리 초기화 - 연비 구하는 기능 getDistancePerLiter() 상수를 사용하여 return Constant - 여행 거리를 구하는 기능 getTripDistance() 멤버변수를 반환
- 자동차 구현클래스들은 RentCar 추상 클래스를 상속받고, RentCar는 Car 인터페이스를 구현한다.
- 초기 카드덱 생성시 Collections.shuffle() 메소드를 통해 카드를 섞는다.
- 카드를 추가하는 addCard() 메서드 추가
- 게임 시작 시, 두 장의 카드를 배분하는 deal() 메서드 생성
- checkAceOneOrEleven() 메서드 추가하고, 11을 더해도 버스트가 되지 않으면 에이스를 11로 취급하도록 수정
- getCardNames(): 참여자가 가진 카드 리스트 반환 - getAllCards(): 참여자가 가진 모든 카드의 이름을 문자열로 join해 반환
- 대신, getName() 메서드 추가
- Gmae 내 결과 산출 기능 메소드 분리 - dealer와 players를 전달하여 GameResult 클래스에서 최종결과 산출
Rok93
left a comment
There was a problem hiding this comment.
세라님 안녕하세요. 🤗 블랙잭 미션을 함께하게 된 김경록입니다. 🙇♂️
블랙잭 미션 구현 잘해주셨네요! 👍
몇몇 피드백 남겨두었으니 확인해서 반영해주세요! 🙏
이해가 잘 안되거나 어려운 부분은 언제든지 DM 주세요! 😉
| @@ -0,0 +1,19 @@ | |||
| package rentcar.domain; | |||
|
|
|||
| public interface Car { | |||
|
|
||
| import java.math.BigDecimal; | ||
|
|
||
| public abstract class RentCar implements Car { |
There was a problem hiding this comment.
인터페이스와 추상 클래스 동시 활용 👍
이펙티브 자바 - 아이템 20의 내용 중 한 구절
한편, 인터페이스와 추상 골격 구현(skeletal implementation) 클래스를 함께 제공하는 식으로 인터페이스와 추상 클래스의 장점을 모두 취하는 방법도 있다. 인터페이스로는 타입을 정의하고, 필요하면 디폴트 메서드 몇 개도 함께 제공한다. 그리고 골격 구현 클래스는 나머지 메서드들까지 구현한다. 이렇게 해두면
단순히 골격 구현을 확장하는 것만으로 이 인터페이스를 구현하는 데 필요한 일이 대부분 완료된다. 바로템플릿 메서드 패턴이다.
출처: 이펙티브 자바 - 아이템20 추상 클래스보다는 인터페이스를 우선하라
템플릿 메서드 패턴을 의도하신건지는 잘 모르겠지만, 이런 패턴이였구나!? 정도로 알고 지나가면 좋을 것 같아요! 😃
| } | ||
|
|
||
| private void playerTurn(CardDeck deck, Players players) { | ||
| for (Player player : players.get()) { |
There was a problem hiding this comment.
players의 상태 값을 외부에 꺼내서 직접 로직을 짜는 것이 아니라 players 객체에게 메시지를 보내보면 어떨까요? 🤗
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class Players { |
There was a problem hiding this comment.
Players가 아니라 Player와 Dealer의 상위 클래스인 Participants로 만들어보면 어떨까요? 🤗
그러면 Game#init에서 dealer와 player의 deal을 따로 실행시킬 필요 없이, participants#deal를 한 번만 호출하면 될 것 같아요. 👀
| public static FinalScoreDTO from(Dealer dealer) { | ||
| return new FinalScoreDTO( | ||
| "딜러", | ||
| dealer.getScore(), | ||
| dealer.getAllCards() | ||
| ); | ||
| } | ||
|
|
||
| public static FinalScoreDTO from(Player player) { | ||
| return new FinalScoreDTO( | ||
| player.getName(), | ||
| player.getScore(), | ||
| player.getAllCards() | ||
| ); | ||
| } |
There was a problem hiding this comment.
딜러 또한 name 상태를 가지고 name을 "딜러"라고 지정하면 어떨까요? 🤔
그러면 아래와 같이 Player와 Dealer를 받는 정적 팩토리 메서드를 따로 만들 필요가 없을 것 같아요. 👀
| public static FinalScoreDTO from(Dealer dealer) { | |
| return new FinalScoreDTO( | |
| "딜러", | |
| dealer.getScore(), | |
| dealer.getAllCards() | |
| ); | |
| } | |
| public static FinalScoreDTO from(Player player) { | |
| return new FinalScoreDTO( | |
| player.getName(), | |
| player.getScore(), | |
| player.getAllCards() | |
| ); | |
| } | |
| public static FinalScoreDTO from(Participant participant) { | |
| return new FinalScoreDTO( | |
| participant.getName(), | |
| participant.getScore(), | |
| participant.getAllCards() | |
| ); | |
| } |
| public final static int BUST_LIMIT = 21; | ||
| public static final String WIN = "승"; | ||
| public static final String PUSH = "무"; | ||
| public static final String LOSE = "패"; |
There was a problem hiding this comment.
상수를 모아둔 Constant 클래스를 따로 둔 이유가 있을까요? 🤔
상수를 사용하는 위치에 직접 정의해서 사용하는 것이 좋지 않을까요? 🤗
지금처럼 상수를 모은 클래스를 따로 두게 되면, 유지보수 관점에서 좋지 않다고 생각해요. 👀
먼저 상수의 개수가 늘어날수록 Constant 클래스의 크기가 거대해질 거에요. 수정하려고 하는 상수를 찾기가 힘들어질 거에요.
또한 코드를 읽을 때도, 이 상수들이 어떤 값인지 알기 위해서는 (읽고 있는 코드 위치를 벗어나) Constant 클래스에서 확인을 해야해요. 🥲
WIN, PUSH( DRAW와 같은 무승부라는 뜻의 네이밍이 좋지 않을까요?), LOSE는 GameResult라는 공통 요소라고 생각되요. 🤔 동일한 성질의 상수들을 enum class로 묶을 수 있을 것 같아요. 😃
|
|
||
| import java.util.List; | ||
|
|
||
| public class Participant { |
안녕하세요😀
박지현(@jihyunhillpark) 님과의 페어 프로그래밍을 통해
연료 주입과 블랙잭 미션을 진행했습니다!
감사합니다 : )