구현한 미션을 리뷰하며 어떤 것을 배웠고 어떤 점이 부족했는지 정리합니다.
자동차 경주 게임 미션 코드 Github
각 자동차에 이름을 부여할 수 있다. 자동차 이름은 5자를 초과할 수 없다.
전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
자동차 이름은 쉼표(,)를 기준으로 구분한다.
전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4이상일 경우이다.
자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한명 이상일 수 있다.
Car 객체의 원시값을 포장하여 이름(Name)과 위치(Position)을 일급 객체로 만들었고, 그로인해 이름의 길이에 대한 유효범위 예외처리도 Name 클래스에 책임을 부여하도록 했다.
이로 인해 프로그램 전체에서 원시값이 아닌 일급 객체로 사용하면서 안전한 코드가 될 수 있다.
또한, 의미있는 값을 클래스로 나타내어 그 값에 맞는 명확한 의미로 나타낼 수 있는 장점도 있다.
Car 객체를 불변 객체로 만들어보면서 불변객체의 이점에 대해 알게되었다.
불변객체로 만들면서 외부에 의해 인스턴스의 데이터가 변하지 않는 안전한 코드가 될 수 있었다.
하지만, 인스턴스가 자주 만들어져 성능 저하의 문제가 될 것 같지만, 성능상 크게 문제가 되지 않는다면
불변 객체로 사용하는게 안전한 코드가 될 것 같다.
public class Position {
private final int position;
public Position(int position) {
if(position < 0) {
throw new IllegalStateException("Position은 음수가 될 수 없다");
}
this.position = position;
}
public Position move() {
return new Position(position + 1); // return this.postion++;
}
}
너무 많은 책임을 가지고 있는 클래스의 로직을 분리하여 책임을 위임하도록 리팩토링 했다.
분리된 클래스나 메서드로 인해 테스트하기 쉬운 코드가 되었다.
일급 객체, 일급 컬렉션으로 만들다보니 무의식적으로 객체를 꺼내서 사용한적이 생긴것 같다.
view단을 제외한 도메인 내에서는 getter 메서드를 사용하여 객체 내부를 꺼내서 사용하거나 테스트하는 것을 줄이고, 객체에 메시지를 보내기 위해 연습이 필요하겠다.
기존에는 이름(name)만 파라미터로 받고 이동횟수를 0으로 초기화하여,
임의의 이동횟수가 들어간 객체가 생성되지 않게 생성자를 하나만 사용했다.
실수로라도 잘못된 객체가 만들어질 수 있는 방법을 차단하기 위한 의도로 로직에 불필요한 생성자를 만들지 않았다.
하지만, 테스트를 위해 특정 Position을 만들기 위해 이동 메서드를 불필요하게 반복하여 테스트를 위한 상태로 만들어야 했고, 테스트 코드에서 상태를 만들기 위해 반복되는 메서드가 불필요하게 느껴졌다.
결론으로, 테스트를 위해 생성자를 사용하는 것도 하나의 방법이라고 하여 생성자를 추가했고
테스트 상황에 맞는 객체를 생성자로 쉽게 만들수 있도록 했다.
public Car(String name) {
this.name = new Name(name);
this.position = new Position(0);
}
public Car(String name, int moveCount) {
this.name = new Name(name);
this.position = new Position(moveCount);
}
규칙적이지 않은 테스트명이나 @DisplayName을 사용했더라도 설명이 명확하지 않은 테스트가 많았기에, 규칙적인으로 테스트 코드 이름을 부여할 필요가 있었다. 일관적으로 규칙을 따르기가 어려웠지만 최대한 신경써서 작성하려 했다.
가장 좋아보인 메서드명 규칙은 <메서드명테스트상태기대결과> 인데, 메서드 이름이 변경되면 테스트 이름을 변경해야 하는 단점이 있다. ex) CarMove_NumberMoreThan4_CanMoveTest
일급 객체와 일급 컬렉션을 만들면서 더 안전한 코드로 개발할 수 있었다.
특히 일급 객체로 만들면서 자연스럽게 객체에 메시지를 보내는 습관을 가질 수 있었지만,
view 단에서 사용하기 위해 작성한 getter 메서드를 1번 쓰게 된 상황이 생겼고, 알아차리기 어려웠다.
더 신경써서 객체에 메시지를 보낼 수 있도록 노력해야겠다.
여전히 TDD는 어렵게 느껴지지만, 작은 단위부터 구현해가면서 연습하니 처음보다 훨씬 접근하기 쉬워졌고, 놓치는 부분도 적은 것 같다.
또한, 꼼꼼하게 작성한 테스트 코드는 리팩토링할 때 빠르게 확신을 가질 수 있게 해줌을 다시 한번 느끼면서 테스트 코드 작성에 많이 신경써야겠다.