-
Notifications
You must be signed in to change notification settings - Fork 0
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
켈리 3 & 4 제출 합니다. #25
base: kelly6bf
Are you sure you want to change the base?
켈리 3 & 4 제출 합니다. #25
Conversation
* docs: 기능 명세서 초안 작성 * feat(position): Position 인스턴스 생성 로직 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(inputView): 사용자로부터 명령을 입력받는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * fix(position): 위치 객체에서 체스 도메인 용어를 사용하도록 변경 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(board): 체스판의 말을 시작 위치로 배치하는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(outputView): 체스판 출력 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * docs(readme): 2단계 기능 요구사항 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(/position): 위치정보와 관련된 클래스들을 한 패키지로 모음 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(position): Position 생성자 파라미터 순서 변경 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(unitVector): 8방위를 나타내는 단위 벡터 객체 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(position): 현재 위치에서 백터를 누적한 새로운 위치를 생성하는 로직 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(orthogonalMoveStrategy): 직선 방향으로 이동 가능 여부를 확인하는 전략 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(continuousMoveStrategy): 이동 가능한 방향벡터와 이동 횟수 제한을 가지는 연속 이동 전략 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(boardInitializer):체스판 초기화 책임 분리 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(continuousMoveStrategy): 스트림 내의 Predicate 메서드 분리 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(board): 체스 말을 이동시키는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(knightMoveStrategy): 나이트 이동 전략 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(pawnMoveStrategy): 폰의 이동 전략 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * test(boardTest): 기물을 이동시키는 로직의 테스트 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(board): 이동 불가능한 경우별 예외에 메시지 구분 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(inputView): 사용자의 명령을 입력받는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(chessController): 팀을 번갈아 가며 게임을 진행하는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * test(knightMoveStrategyTest): 나이트 움직임에 대한 테스트 코드 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * test(pawnMoveStrategyTest): 폰 움직임에 대한 테스트 코드 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * style(positionTest): 테스트 설명 수정 Co-authored-by: Hyunguk Ryu <[email protected]> * feat(pieceFactory): PieceType을 전달받아 올바른 Piece를 생성하는 객체 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * test(boardTest): Board 출발지 -> 목적지 기물 배치 성공 & 실패 테스트 추가 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(continuousMoveStrategy): 메서드 이름 변경 Co-authored-by: Hyunguk Ryu <[email protected]> * style(position): 미사용 TODO 삭제 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(chessController): 사용자 입력에 따라 게임을 진행하는 기능 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor(requestDto): 명령 인자에서 Optional 제거 Co-authored-by: Hyunguk Ryu <[email protected]> * fix(pawnMoveStrategy): 폰이 직선 이동에서 상대 기물을 공격하는 버그 수정 Co-authored-by: Hyunguk Ryu <[email protected]> * refactor: position 도메인 객체 수정 - 기존 클래스명을 더 명확하게 변경함. - 부족한 테스트 케이스를 추가함. - 메서드 파라미터를 더 명확한 타입으로 개선함. Co-authored-by: Hyunguk Ryu <[email protected]> * refactor: direction 도메인 추상화 - direction enum들을 MovementDirection으로 추상화 함. - 테스트를 수정함. Co-authored-by: Hyunguk Ryu <[email protected]> * feat: Bishop 구현 Co-authored-by: Hyunguk Ryu <[email protected]> * feat: Rook 구현 Co-authored-현by: Hyunguk Ryu <[email protected]> * feat: King 구현 Co-authore현d-by: Hyunguk Ryu <[email protected]> * feat: Queen 구현 Co-authore현d-by: Hyunguk Ryu <[email protected]> * feat: Knight 구현 * feat: Pawn 구현 Co-authored-현by: Hyunguk Ryu <[email protected]> * refactor: board 패키지 생성 * refactor: Piece 도메인 클래스에 Type 추가 Co-authored-by: Hyu성nguk Ryu <[email protected]> * remove: 기존 코드 제거 Co-authored-by: Hyunguk Ryu <가[email protected]> * refactor: piece 패키지 정리 * refactor: board 도메인 개선 * refactor: view & dto 개선 * docs: 기능 명세서 개선 * refactor: 상태 페턴 적용 * other: 상태에 Controller를 넘기는 케이스 코드 추가 * refactor: import 와일드 카드 제거 * refactor: 기물 이동 메서드명 변경 및 불필요한 메서드 분리 제거 * refactor: Piece 이동 시 Board 클래스를 입력받도록 리펙토링 * refactor: Bishop & Rook의 방향 유효성 검증을 CommonMovementDirection에 위임 * refactor: BoardInitializer 개선 --------- Co-authored-by: Hyunguk Ryu <[email protected]> Co-authored-by: Hyunguk Ryu <가[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
대짱켈리~ 체스 미션 고생 많았어요 😤
방학 기간동안 스프링 뿌셔서 레벨 2도 달려봅시다 👍👍
public void movePiece(final Position source, final Position destination) { | ||
chessGame.movePiece(source, destination); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 비즈니스 로직이라고 봐도 될 것 같은데
요 로직이 왜 컨트롤러에 있을까용? 사용처가 안보입니다 😄
if (values.length != POSITIONS_VALUES_SIZE) { | ||
throw new IllegalArgumentException("잘못된 위치값입니다."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰어께 3,4 단계 리뷰를 받으면서,
에러메시지는 개발자가 아닌 사람도 알아볼 수 있게 작성하는 것이 좋다. 라는 피드백을 받았는데
켈리도 에러메시지에 신경을 더 써보면 좋을 것 같아 리뷰 남겨용 😄
if (values.length != COMMAND_WITH_POSITIONS_SIZE) { | ||
throw new IllegalArgumentException("잘못된 출발지/도착지입니다."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"move b2 b4" 의 split 사이즈가 3이 아닌 것과,
"잘못된 출발지/도착지입니다." 라는 에러메시지가 매칭이 안되는 것 같아요. 🤔
public void checkBishopMovableMovement() { | ||
List<CommonMovementDirection> bishopMovableMovement = List.of(UP_RIGHT, UP_LEFT, DOWN_RIGHT, DOWN_LEFT); | ||
|
||
if (!bishopMovableMovement.contains(this)) { | ||
throw new IllegalArgumentException("비숍이 이동할 수 있는 방향이 아닙니다."); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나는 각 기물이 이동할 수 있는 Direction을 가지고 스스로 판단하도록 구현했었는데
켈리는 각 기물이 Direction에 물어봐서 이동할 수 있는 방향인지 설계했네
이렇게 구현했을 때 어떤 점이 좋았고, 어느 부분에서 안좋게 느꼈는지 공유해주면 좋을듯 👍
public Piece(final PieceColor color) { | ||
this.color = color; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Piece 생성자가 자식 클래스에만 사용된다면 접근제한자를 protected로 변경해주는 것도 좋을듯 👍
if (rowDistance == 0 && columnDistance == 0 | ||
|| (!(Math.abs(rowDistance) == Math.abs(columnDistance)) | ||
&& !(rowDistance == 0 || columnDistance == 0))) { | ||
throw new IllegalArgumentException(("상/하/좌/우 혹은 대각선으로 이동할 수 없는 칸입니다.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 개인적으로 중첩 조건문에서 메서드 분리 없이 부정연산자까지 쓰면 가독성이 엄청 안좋아진다 생각합니다 😎
@Override | ||
public void execute(final GameController gameController) { | ||
if (gameController.gameStatus() != GameStatus.WAITING) { | ||
throw new IllegalArgumentException("지금 실행할 수 있는 명령어가 아닙니다."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Command
의 매개변수로 컨트롤러가 들어오네요
저는 Service를 매개변수로 넘겨서 서비스 메서드 호출로 기능을 진행하고,
execute가 게임 상태를 반환하여 상태에 따른 판단을 컨트롤러에서 진행했는데
켈리는 저랑 정반대인 것 같아 의도가 궁금합니다 🤔
저는 컨트롤러가 매개변수로 들어오는게 뭔가 조금 어색한 것 같아요
public static JdbcConnectionPool getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
private void initializeConnectionPool() { | ||
pool = new ArrayBlockingQueue<>(INITIAL_POOL_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우.. 커넥션 풀까지 구현하다니 👍👍
전 계획만 세우다가 막상 하려니까 막막해서 포기했는데 잘 구현하셨네요
create table current_player_color | ||
( | ||
id bigint auto_increment primary key, | ||
player_color varchar(10) not null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네이밍 때문에 오히려 가독성이 안좋아진 케이스라고 생각합니다.
그냥 간단하게 테이블 명명을 current_turn, turn 으로 해줘도 좋을 것 같아요.
Turn을 의미하는건가...? 라는 인지적 비용이 한 번 더 발생하네용 😄
public static Score of(final Board board, final PieceColor pieceColor) { | ||
Map<Position, Piece> piecePositions = board.piecePositions(); | ||
double existTargetColorPiecesScoreSum = sumExistTargetPiecesScore(piecePositions, pieceColor); | ||
double scoreValue = existTargetColorPiecesScoreSum - calculateDecreaseScoreForExistSameFilePawns(piecePositions, pieceColor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 점수 계산 로직을 Board에서 분리하고 싶었는데
뭔가 매개변수로 Board를 넘겨줘서 하는게 자연스러운건가...? 확신이 없어서 이렇게 못했었던 것 같아요
켈리가 이렇게 구현한 이유를 공유해주면, 뭔가 확신을 얻을 수 있을 것 같아요
아니면 따로 이렇게 구현했을 때 리뷰어로부터 리뷰를 받은 게 있었는지 궁금합니다! 🤗
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
레벨 1 수고많았어 켈리!!
방학 푹 쉬고 레벨 2도 화이팅
|
||
|
||
Co-authored-by: Hyunguk Ryu <[email protected]> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
진짜 사소한 의견이긴 한데 공백도 컨벤션이니 위의 두줄은 없어도 되지 않을까..?
.filter(it -> it.value.equalsIgnoreCase(values[COMMAND_INDEX])) | ||
.map(it -> it.gameCommand.apply(values)) | ||
.findAny() | ||
.orElseThrow(() -> new IllegalArgumentException("유효하지 않은 명령어입니다!")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
유효하지 않은 명령어입니다! 메시지만 !로 문장을 끝낸 이유가 궁금!
private static final String FAILED_INITIALIZE = "커넥션 풀 초기화에 실패했습니다."; | ||
private static final String FAILED_TO_GET_CONNECTION = "커넥션 획득에 실패했습니다."; | ||
private static final String FAILED_RELEASE = "커넥션 해제에 실패했습니다."; | ||
private static final String FAILED_CLOSE = "커넥션 종료에 실패했습니다."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 도메인에서 발생할 수 있는 예외에선 예외 메시지를 리터럴로 두었지만 커넥션과 관련된 예외 메시지에선 상수로 관리한 이유가 궁금!
package domain.board; | ||
|
||
|
||
import domain.piece.Bishop; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
진짜 사소하지만 공백 하나 없어도 될듯!
|
||
public static File of(final String value) { | ||
return Arrays.stream(values()) | ||
.filter(file -> file.name().equals(value.toUpperCase())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum의 name 메서드는 어떨때 사용하는 게 좋을까?
|
||
@Override | ||
public List<PieceEntity> findAll() { | ||
final String query = "SELECT * FROM piece"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final 이 붙은건 네오의 코드 복붙해오는 과정에서 사용했다고 생각하는데 final을 붙일거면 전부다 필사적으로 붙여야 한다고 생각!
ResultSet resultSet = preparedStatement.executeQuery(); | ||
return createPieceEntities(resultSet); | ||
} catch (SQLException e) { | ||
throw new RuntimeException(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SQLException을 잡고 RuntimeExcpetion으로 넘기기 보다 IllegalStatementException을 던지는건 어때?
private static PieceEntity convertPieceEntity(final Piece piece, final Position position) { | ||
return new PieceEntity(piece.pieceType(), piece.pieceColor(), position.file(), position.rank()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 메서드가 Board 안에 있는게 맞을지 아니면 PieceEntity 안에 정적 팩터리 메서드를 넣는게 나을지 켈리는 어떻게 생각해?
} | ||
|
||
public void checkBishopMovableMovement() { | ||
List<CommonMovementDirection> bishopMovableMovement = List.of(UP_RIGHT, UP_LEFT, DOWN_RIGHT, DOWN_LEFT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 List는 상수로 분리해도 되지 않을까?
@Override | ||
public PieceType pieceType() { | ||
return PIECE_TYPE; | ||
} | ||
|
||
@Override | ||
public double score() { | ||
return pieceType().score(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실상 getter인데 메서드에 get을 사용하지 않는 이유가 궁금!
No description provided.