2021-02-23-TIL
2021-02-23-TIL
체스 보드 테스트
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void findPiece() {
board.initialize();
assertThat(board.findPiece("a8"))
.isEqualTo(Piece.createBlackRook(new Position(0, 7)));
assertThat(board.findPiece("h8"))
.isEqualTo(Piece.createBlackRook(new Position(7, 7)));
assertThat(board.findPiece("a1"))
.isEqualTo(Piece.createWhiteRook(new Position(0, 0)));
assertThat(board.findPiece("h1"))
.isEqualTo(Piece.createWhiteRook(new Position(7, 0)));
}
체스 표기법의 칸 이름("a8")으로 기물을 찾는 테스트다. 네 모서리의 룩이 올바른 색과 위치로 놓였는지 확인한다. isEqualTo()로 기물 객체를 비교하려면 Piece가 equals()를 값 기준으로 오버라이딩하고 있어야 한다.
코드 리뷰에서 남긴 의견
- Board
whitePawnSize()와 blackPawnSize()를 따로 구현한 이유가 있나요? 어차피 list.size()로 가져올 것 이라면 없애는 것도 좋은 것 같습니다.
List 를 모두 따로 관리하는데 각 piece의 size를 구하는 메서드가 별도로 존재하지 않는다. pieceCount에서 list.size()를 모두 더한 값을 리턴해야 테스트를 통과할 것 입니다.
getDotOnBoard() 는 그냥 문자열 리터럴을 리턴하는데 그냥 변수랑 다른점이 없는 것 같습니다. 이것을 final 상수로 선언하는 것이 나을 것 같습니다.
- StringUtils
utils.StringUtils.appendNewLine() 을 getBoard()에서 사용하지 않습니다. 그리고 getBoard()라는 메서드명은 자칫 getter와 그 기능이 혼동이 올 수 있는 것 같습니다.
- PieceTest
verifyPiece()는 논리적으로 같은 단위이므로 assertAll로 묶어도 좋을 것 같습니다.
getWhitePawnInstance() 에서 Instance 라는 이름은 굳이 필요가 없을 것 같습니다.
assertAll()은 JUnit 5의 그룹 assertion이다. 일반 assertion을 여러 줄 나열하면 첫 번째 실패에서 테스트가 멈춰 나머지 결과를 알 수 없다. assertAll()로 묶으면 안의 assertion을 모두 실행한 뒤 실패한 것들을 한꺼번에 보고한다. 기물 하나의 색, 이름, 위치처럼 함께 확인해야 의미가 있는 값들을 묶기에 맞다.
정적 팩토리 메서드 이름
팩토리 메서드에서 get ~ instance라는 이름은 싱글톤에서 많이 사용한다. create ~ 라는 이름을 팩토리 메서드에서 많이 사용한다. static factory 메서드. get은 리턴값이 있다는 의미가 명확한 의미가 좋다.
1
2
3
4
5
6
7
8
9
10
11
12
13
- from: 하나의 매개변수를 받아서 인스턴스를 생성
- of: 여러개의 매개변수를 받아서 인스턴스를 생성
- instance or getInstance: 인스턴스를 반환하지만 동일한 인스턴스임을 보장하지 않는다.
- 보통 singleton을 구현할때 많이 사용하는 네이밍이지만 singleton이랑은 무관하게 매번 신규 생성될 수 있다.
create or newInstance: 매번 새로운 인스턴스를 반환한다.
instance or getInstance 의 서브셋 개념이라고 볼 수 있을듯
getXxxx: getInstance와 같으나 호출하는 클래스와 다른 타입의 인스턴스를 반환할때 사용
예를들어 Date.getInstance() 는 Date 타입의 인스턴스를 반환하지만 Date와 상관없는 Period 타입을 반환한다면 Date.getPeriod() 가 된다.
newXxxx: getXxxx와 같으나 매번 새로운 인스턴스를 반환한다.
출처: https://multifrontgarden.tistory.com/255 [우리집앞마당]
JDK에서도 이 관례를 확인할 수 있다. Date.from(Instant)는 매개변수 하나로 인스턴스를 만들고, EnumSet.of(...)는 여러 원소로 집합을 만든다. Calendar.getInstance()는 현재 날짜와 시각으로 초기화된 Calendar를 돌려주며, Files.newBufferedReader(Path)는 호출할 때마다 파일을 새로 열어 BufferedReader를 돌려준다. Files가 아닌 BufferedReader 타입을 돌려주므로 newXxx 형태가 된다.
Git 명령어
1
2
3
git log --oneline
git stash // 임시저장 했다가
git stash pop // 다시 되돌리기
git log --oneline은 커밋을 한 줄에 하나씩, 축약한 해시와 메시지만 보여 준다. 메모에는 git --log oneline으로 적혀 있었는데 이렇게 입력하면 동작하지 않으므로 바로잡았다.
git stash는 아직 커밋하지 않은 작업 디렉터리와 스테이징 영역의 변경을 따로 저장해 두고, 작업 디렉터리를 마지막 커밋 상태로 되돌린다. 급하게 다른 브랜치로 옮겨야 할 때 쓴다. git stash pop은 저장해 둔 변경을 현재 작업 트리에 다시 적용하고 stash 목록에서 지운다. 적용하다 충돌이 나면 목록에서 지워지지 않으므로, 충돌을 해결한 뒤 git stash drop으로 직접 지운다. 목록에 남겨 두고 적용만 하려면 git stash apply를 쓴다.
줄바꿈 문자
Collections.lineSeparator
Collections에는 이런 메서드가 없고, 운영체제에 맞는 줄바꿈 문자를 돌려주는 메서드는 System.lineSeparator()다. Javadoc에 따르면 UNIX에서는 "\n", Windows에서는 "\r\n"을 돌려준다. 보드를 문자열로 출력할 때 "\n"을 직접 쓰는 대신 이 값을 쓰면 실행 환경에 맞는 줄바꿈이 들어간다.
catch와 throws
오류가 발생해도 끝나지 않았으면 좋겠다하는 에러는 catch로 잡고, throws는 상위 객체로 책임을 떠넘기는 의미를 가진다.
Oracle 튜토리얼은 이 선택을 “누가 이 예외를 처리하기에 알맞은가”로 설명한다. 메서드 안에서 복구할 방법이 있으면 catch로 잡아 처리한다. 반대로 라이브러리처럼 호출하는 쪽의 사정을 다 알 수 없다면, 예외를 잡지 않고 throws로 선언해 호출 스택 위쪽의 메서드가 처리하게 하는 편이 낫다. 정확히는 throws가 넘기는 대상은 상위 객체가 아니라 이 메서드를 호출한 쪽이다. 또 RuntimeException 계열의 unchecked 예외는 throws에 적지 않아도 된다.
댓글
아직 댓글이 없습니다