Skip to content

Perhona/java-racingcar

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

자동차 경주 게임


미션을 완수하고 배운 내용 by Perhona

  • JUnit5, assertJ 를 사용한 단위테스트
  • 테스트 의도를 명확히 드러내는 테스트 네이밍 컨벤션
  • 실패하는 테스트 > 성공하는 테스트 > 리팩토링 3단계의 테스트 사이클 적용
  • 값객체를 사용하여 객체의 조건을 보장하는 역할을 위임
  • 상태와 로직을 따로 관리할 수 있는 일급 컬렉션의 사용
  • 테스트하기 어려운 값(ex.Random)에 대한 의존을 역전시켜 특정 구현에 의존하지 않고 테스트하기 쉬운 코드로 변경
  • 매직 넘버에서 의미있는 상수로 변환하기
  • 유지보수성을 고려하여 메서드가 한가지 역할을 할 수 있도록 메서드 분리

진행 방법

  • 자동차 경주 게임 요구사항을 파악한다.
  • 요구사항에 대한 구현을 완료한 후 자신의 github 아이디에 해당하는 브랜치에 Pull Request(이하 PR)를 통해 코드 리뷰 요청을 한다.
  • 코드 리뷰 피드백에 대한 개선 작업을 하고 다시 PUSH한다.
  • 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다.

온라인 코드 리뷰 과정


calculator.CalculatorTest

요구사항 분석

To do

  • 빈 문자열 혹은 null 값을 입력할 경우 0을 반환한다. ("" => 0, null => 0)
  • 숫자 하나를 문자열로 입력할 경우 해당 숫자를 반환한다. ("1" => 1)
  • 쉼표 혹은 콜론을 구분자로 가지는 문자열을 전달하는 경우, 구분자를 기준으로 분리한 각 값의 합을 반환한다. ( "1,2:3" => 6)
  • 문자열 계산기에 숫자 이외의 값 또는 음수를 전달하는 경우, RuntimeException 예외 throw한다. ("-1:2:3" => RuntimeException)
  • 커스텀 구분자를 지정할 수 있다. ("//;\n1;2;3" => 6)

Feedback

  • junit4 의존성 삭제
  • 유닛 테스트 네이밍 코드 컨벤션 적용
  • 한 번만 수행해도 되는 코드 분리 (Patter.compile / split)
  • 양수임을 보장하는 값 객체를 활용한 숫자 이외의 값 혹은 음수 검증
  • Array => List 변경
  • ParameterizedTest를 활용한 여러 개의 테스트 수행

Feedback 23.11.09

  • 객체를 만들었다면 객체간 소통이 되도록 작성해보기(PositiveNumber class)
    • 반환 값을 PositiveNumber로 하여 반환값을 보장하고, 생성자에서 예외를 던지도록 변경

racingCar.racingCarTest

step3

요구사항 분석

원칙

  • README.md 파일에 구현할 기능 목록을 정리한다.
  • git commit 단위는 아래 정리한 기능 목록 단위로 추가한다.
  • Java 코드 컨벤션을 지키면서 프로그래밍한다. (IntelliJ idea Code Style.java)
  • else 예약어를 쓰지 않는다.
  • UI 로직을 제외한 모든 로직에 단위 테스트를 구현한다.
  • 핵심 로직 구현 코드와 UI 담당 로직을 구분한다.
  • UI 로직은 별도 클래스를 추가해 분리한다. (InputView, ResultView)

To do

  • 자동차 대수와 횟수를 사용자에게 입력받는다. (3, 5)
  • 자동차 대수만큼 자동차를 생성한다.
  • 전진 조건은 랜덤 값을 구해 4 이상인 경우이다.
  • 각 자동차는 멈추거나 전진한다,(움직인다)
  • 결과를 화면에 출력한다. 출력 시점의 제약은 없다.

Feedback 23.11.09

  • 사용자 입력을 받기 위해 InputView를 매번 생성하는 것이 아닌, 필요한 정보를 얻을 수 있는 메서드를 별도 구현
  • 애플리케이션이 실행되는 main의 구조 변경
  • RacingCar에 static으로 구현된 메서드를 모두 별도의 클래스로 옮겨 각자 책임을 부여
  • List 타입 변수를 CarList라는 일급 컬렉션으로 변경해서 관리
  • 전체적으로 OOP의 개념에 입각해 여러 객체를 도출하고 객체간 메시지를 주고받으며 협력하도록 구조 개선

Feedback 23.11.12

  • 일급 컬렉션 CarList의 클래스명을 컬렉션 성격을 드러내지 않도록 변경한다.
  • InputView에서 사용자에게 입력받은 값을 InputView의 멤버변수, 정적변수로 두면 객체 재활용 시 문제가 됨. InputView에게 필요한 변수를 얻는 메서드로 구현하자.
  • 콘솔에서 출력하는 부분은 언제든지 바뀔 수 있으므로, CarList 내 ResultView 부분은 모두 제거하고, CarList에게 얻은 값을 ResultView에게 전달하도록 구현
  • ResultView 외 위치한 println()의 위치 변경
  • 현재 자동차 생성 시 CarList 생성 후 addCar, moveByTryCount의 순서가 보장되지 않는다. 팩터리 메서드를 이용해 CarList를 생성할 때 미리 Car객체를 생성하도록 해보자.
  • 현재 작성한 Car.move()의 결과값 범위 테스트보다는, 확실한 상태에 대한 Test를 작성하자. 의존성 역전에 대해 알아보고 적용해볼 것.
  • CarList.moveByTryCount()에 대한 Test도 위에 언급한 바와 같다. 확실한 상태값에 대한 테스트를 진행하고, for loop / if-else와 같은 반복, 조건문을 지양한다.
    • 테스트 삭제
  • getRandomNumber() Test는 굳이 필요가 없을 듯 하다.

Feedback 23.11.13

  • 의존성 역전을 통해 핵심 메서드인 move() 개선 + InputView, ResultView
  • 현재 addCar()는 직접 제어할 수 없는 상태(테스트하기 힘들다.) 추후 개선 요망

step4

요구사항 분석

원칙

  • indent depth는 2가 넘지 않도록 구현한다.
  • 함수 길이가 15라인을 넘어가지 않도록 구현한다.

To do

  • 각 자동차의 이름을 부여할 수 있다.
  • 자동차 이름은 5자를 초과할 수 없다.
  • 자동차 이름은 쉼표를 기준으로 구분한다.
  • 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
  • 자동차 게임을 완료한 후 누가 우승했는지를 알려준다.
  • 우승자는 여러명일 수 있다.

Feedback

  • Car의 원시값 name을 포장한 CarName 클래스 추가
  • move의 이동 조건인 랜덤값 3 초과에서 '3'을 상수로 변환
  • Winners 객체의 우승자 선정 역할을 Cars가 하도록 변경
    • 우승자 선정 로직 수정
  • RacingCarGame 내 일부 멤버변수 -> 지역변수 위치 이동
  • RacingCar moveOnce() 결과 callback 함수로 호출
  • RacingGameRequest 역할 분리
    • Cars 생성은 Cars 역할로 분리

About

TDD, 클린코드를 적용하여 자동차 경주용 게임을 구현

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%