2주차 미션은 Java로 자동차 경주 게임을 구현하는 것이다. 문자열로 주어진 자동차 이름들을 입력받고, 주어진 횟수 동안 자동차를 무작위로 전진시킨 뒤 최종 우승자를 출력하는 프로그램이다. 이번 미션은 단순 구현보다 객체 분리와 책임 분배의 중요성을 배우는 데 초점이 맞춰져 있다.
지난 주차와 마찬가지로 README.md에 체크리스트를 작성하며 시작했다.
# java-racingcar-precourse
## ✅ 실행 환경 확인
- Java 버전 21로 실행 확인 (`java -version → 21 출력`)
- IntelliJ/Gradle JVM 모두 21로 설정 (`.\gradlew.bat --version`)
- `.\gradlew.bat clean test` 실행 시 **BUILD SUCCESSFUL** 확인
## 📦 저장소 준비
- 미션 저장소 포크 및 로컬 클론 완료
- `README.md`에 기능 목록 작성 후 단계별 커밋 계획 세움
## 💾 커밋 운용
- 기능 단위로 커밋 (feat, fix, refactor 등 **Angular 컨벤션 적용**)
- 커밋 메시지에 구현 기능을 명확히 서술
## ⚙️ 기능 요구 사항
- 경주할 자동차 이름 입력 (쉼표 `,` 기준으로 구분)
- 자동차 이름은 5자 이하만 가능
- 시도할 횟수 입력받기
- 각 자동차는 무작위 값(0~9) 중 4 이상일 경우 전진
- 전진 결과 출력 형식 준수 (`pobi : ---`)
- n회 시도 후 우승자 출력 (`최종 우승자 : pobi, jun`)
- 복수 우승자 처리 시 쉼표로 구분
- 잘못된 입력 시 `IllegalArgumentException` 발생 및 프로그램 종료
## 💬 입출력 요구
- 입력 1: 자동차 이름 목록 (예: `pobi,woni,jun`)
- 입력 2: 이동 횟수 (예: `5`)
- 출력 1: 각 회차별 자동차 전진 결과 표시
- 출력 2: 최종 우승자 안내 (`최종 우승자 : pobi, jun`)
- 예외 발생 시 `[ERROR]`로 시작하는 메시지 출력
- 출력 형식 정확히 일치해야 함
## 💻 프로그래밍 요구
- 진입점 `Application.main()` 사용
- `build.gradle` 수정 금지, 외부 라이브러리 미사용
- `System.exit()` 호출 금지
- 파일/패키지명 변경 금지
- 자바 코드 컨벤션 및 네이밍 규칙 준수 (Java Style Guide 기반)
- 들여쓰기 depth 2 이내 유지
- 메서드는 한 가지 일만 하도록 분리
- 삼항 연산자 사용 금지
## 🧩 객체 설계 요구
- `Car` 클래스 사용 — `name`, `position` 필드 유지
- `setPosition()` 사용 없이 동작 구현
- `Cars` 일급 컬렉션 형태로 여러 자동차 관리
- 캡슐화 및 책임 분리 원칙 적용
## 📚 라이브러리 사용
- 입력: `camp.nextstep.edu.missionutils.Console.readLine()`
- 랜덤값: `camp.nextstep.edu.missionutils.Randoms.pickNumberInRange(0, 9)`
- `Random`, `Scanner` 직접 사용 금지
## 🧪 테스트 실행
- Windows: `gradlew.bat clean test` 실행
- 모든 테스트 성공 시 **0점 방지 (BUILD SUCCESSFUL in 0s 확인)**
- `ApplicationTest` 내 전체 테스트 통과 필수
## 🧠 학습 목표
- 큰 함수 → 작은 함수로 분리하여 단일 역할 수행
- 1주 차 피드백(네이밍, 들여쓰기, 책임 분리 등) 반영
- 객체지향 설계 및 일급 컬렉션 적용 실습
이번에는 1주차와 달리 클래스 간 책임 분리가 명확한 구조를 목표로 했다.
| 클래스 | 역할 |
| Car | 자동차 이름(name)과 위치(position) 저장, 난수 기반 전진 결정 (move()) |
| Cars | 여러 자동차를 관리하는 일급 컬렉션, 전체 이동 및 우승자 계산 |
| InputView | 사용자 입력 처리 |
| OutputView | 실행 결과 출력 |
| RacingCarController | 전체 게임 흐름 제어 (입력 → 진행 → 출력) |
프로젝트는 아래의 구조를 가진다. MVC 패턴으로 역할과 책임 분리, 그리고 코드의 확장성과 테스트의 용이성을 모두 고려하도록 구현했다.
- model에서는 비즈니스 로직과 상태(Car, Cars)를 집중적으로 관리하고 view에서는 사용자의 입력과 출력만 처리하도록 했다.
- controller는 전체 게임 흐름을 제어하고 model과 view 사이의 다리 역할을 담당한다.
초반에 model에서 출력까지 모두 직접 처리하도록 코드를 작성했다. 그런데 이렇게 하면 곧바로 입출력에 의존성이 생기고, model 클래스의 책임이 불필요하게 커진다는 사실을 경험하게 되었다.
이 과정에서 “한 클래스는 하나의 일만 하라”는 단일 책임 원칙(Single Responsibility Principle)의 의미를 처음으로 실감했다. 핵심 로직은 model에, 출력은 view에 맡기도록 구조를 바꾼 후, 코드가 확실히 더 이해하기 쉬워지고 테스트도 편해졌다.

MVC 패턴 덕분에
- 입력/출력 포맷이 바뀌어도 model이나 controller는 거의 수정이 없게 된다.
- 게임 규칙이 미래에 변경되어도 model 중심으로만 리팩토링하면 된다.
또한, 피드백에서 추천했던 컬렉션을 활용하고자 Cars 클래스를 통해 자동차 리스트의 관리와 우승자 판별 로직을 한 곳에 집중시켰다. 이렇게 하니 코드의 응집도가 높아지고, 컨트롤러나 뷰가 불필요하게 리스트 세부 구현에 의존하지 않아도 되어 전체 구조가 훨씬 명확해졌다.
이렇게 벌써 2주차도 마무리했다. 아직까지 구현 난이도가 높다거나, 구조도를 크게 고민하는 경우는 없었어서 최대한 기본에 집중하며 프로젝트를 진행하고자 하고 있다.

https://github.com/woowacourse-precourse/java-racingcar-8/pull/261
[자동차 경주] 이동건 미션 제출합니다. by mvg01 · Pull Request #261 · woowacourse-precourse/java-racingcar-8
주요 구현 기능 자동차 이름 입력 및 검증 쉼표로 구분된 자동차 이름을 입력받고, 각 이름은 5자 이하로 제한 잘못된 입력 시 IllegalArgumentException 발생 및 프로그램 종료 경주 로직 구현 0~9 사이
github.com
'우아한테크코스 8기 백엔드' 카테고리의 다른 글
| [우테코 8기 BE] 최종시험 후기 및 회고 (0) | 2026.01.24 |
|---|---|
| [우테코 8기 BE] 4 & 5 주차 오픈미션 (0) | 2025.11.24 |
| [우테코 8기 BE] 3주차 로또 리뷰 (0) | 2025.11.02 |
| [우테코 8기 BE] 1주차 문자열 덧셈 계산기 리뷰 (0) | 2025.10.18 |