Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 자동차 경주

## 설명
1. 자동차 이름 입력받기
2. 4이상-> 전진, 4미만->멈춤

## 조건
1. indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록
2. 3항 연산자, else, switch/case 모두 금지
3. 함수(메서드) 길이 15라인 넘지 않도록
4. 함수가 한 가지 일만 할 수 있게
1 change: 1 addition & 0 deletions src/main/java/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쓰지 않는 파일은 삭제해주셔도 괜찮습니다!

24 changes: 24 additions & 0 deletions src/main/java/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
public class Car {
private static final int MOVE_THRESHOLD = 4;

private String name;
private int position=0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드스타일은 아래 단축키를 통해 한 번에 정렬 가능합니다!

  • 윈도우 : Crlt + Alt + L
  • 맥 : Command + Option + L


public Car(String name){
this.name=name;
} //자동차 이름 규칙 강제화

public String getName(){
return name;
}

public int getPosition(){
return position;
}

public void move(int randomNumber){
if(randomNumber>=MOVE_THRESHOLD){
position++;
}
}
}
40 changes: 40 additions & 0 deletions src/main/java/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import java.util.List;

public class Cars {
private final List<Car> cars;

public Cars(List<Car> carList) {
this.cars = carList;
}

public StringBuilder findWinnerNames() {
int maxPosition = findMaxPosition();
return buildWinnerNames(maxPosition);
}

private int findMaxPosition() {
int maxPosition = 0;
for (Car car : cars) {
maxPosition = Math.max(maxPosition, car.getPosition());
}
return maxPosition;
}

private StringBuilder buildWinnerNames(int maxPosition) {
StringBuilder winnerNames = new StringBuilder();
for (Car car : cars) {
appendWinnerName(car, maxPosition, winnerNames);
}
return winnerNames;
}

private void appendWinnerName(Car car, int maxPosition, StringBuilder winnerNames) {
if (car.getPosition() == maxPosition) {
winnerNames.append(car.getName());
}
}

public Car[] getCars() {
return cars.toArray(new Car[0]);
}
}
12 changes: 12 additions & 0 deletions src/main/java/MoveCondition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import java.util.Random;

public class MoveCondition {

public void randomMove(Car car){
Random random = new Random();

int randomNumber = random.nextInt(10); // 0부터 9까지의 랜덤 숫자 생성

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 10도 매직넘버 상수화를 적용시켜보면 어떨까요?
비즈니스 규칙과 연관되어 있으니까요!

System.out.println("랜덤변수 : " + randomNumber);
car.move(randomNumber);
Copy link

@SANGHEEJEONG SANGHEEJEONG Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰를 반영한 흔적이 보이네요 :)
그런데 아직 RandomMove는 1. 랜덤 생성과 동시에 2.자동차를 움직이는 명령을 내리고 있는 것 같아요!
혹시 이 부분에 대해서는 완전한 분리를 이루지 않은 이유가 있는지 궁금합니다!

저는 완전한 분리(car.move 호출을 다른 곳에서)를 제안하고 싶은데요, 이유는 다음과 같습니다.
현재 RandomMove는 랜덤값에 의존하므로 단위테스트가 어려울 것 같아요.
완전히 분리하게 되면 각각의 책임이 명확해집니다. Random을 생성하는 클래스와 움직임을 담당하는 곳이 분리되므로 유지보수 및 확장이 용이하게 변할 것 같아요! 예를 들어, 새로운 자동차를 움직이는 비즈니스 규칙이 추가된다고 가정하면, 결합되어 있는 메서드의 경우 로직이 복잡해질 수 있습니다.

추가로 이 randomMove 메서드는 각각의 자동차가 움직일 때마다 호출되는 메서드 입니다!
그러므로 자동차 수 x 라운드 수 = 호출횟수가 되는데요,
아마 제일 많이 호출되는 메서드일 거라 생각하는데 자동차를 움직일 때마다 항상 Random() 객체를 생성하고 있어
(물론 이 미션에서의 성능차이는 미세하지만) 성능 면에서 불필요한 객체 생성이 반복되고 있는 셈입니다.
이 부분도 한 번 고려해보면 어떨까요?

고은님의 생각을 들려주시면 감사하겠습니다!

}
}
22 changes: 22 additions & 0 deletions src/main/java/RaceController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
public class RaceController {
public void startRace(Cars car, int rounds) {
MoveCondition moveCondition = new MoveCondition();

for (int round = 0; round < rounds; round++) {
runRound(car, moveCondition);
}
System.out.println();
}

private void runRound(Cars cars, MoveCondition moveCondition) {
for (Car car : cars.getCars()) {
moveCondition.randomMove(car);
}

for (Car car : cars.getCars()) {
String dashes = "-".repeat(car.getPosition());
System.out.println(car.getName() + " : " + dashes);
}
System.out.println();
}
}
27 changes: 27 additions & 0 deletions src/main/java/RaceStart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import java.util.Scanner;
import java.util.Arrays;

public class RaceStart {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

int rounds = scanner.nextInt(); //라운드 횟수 입력
int n = scanner.nextInt(); // 차 갯수 입력
Car[] cars = new Car[n];

for (int i = 0; i < n; i++) {
String name = scanner.next();
cars[i] = new Car(name);
}

Cars carsList = new Cars(Arrays.asList(cars));

RaceController raceController = new RaceController();
raceController.startRace(carsList, rounds);

Winner winner = new Winner();
winner.findWinner(carsList);

scanner.close();
}
}
7 changes: 7 additions & 0 deletions src/main/java/Winner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public class Winner {

public void findWinner(Cars cars) {
StringBuilder result = cars.findWinnerNames();
System.out.println(result + "가 최종 우승했습니다.");
}
}
28 changes: 28 additions & 0 deletions src/test/java/TestRace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestRace {

@Test
@DisplayName("4이상 일때만 전진하는지 확인")
void CarMove(){
//given
Car f1 = new Car("f1");
//when
f1.move(4);
//then
assertThat(f1.getPosition()).isEqualTo(1);
}

void CarStop(){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CarStop 메서드에 @test 어노테이션이 빠져있어서 실제로는 테스트가 실행되지 않을 것 같아요.
이 부분 한번 확인해보시면 좋을 것 같습니다!

현재는 자동차의 이동에 대한 부분만 테스트가 작성되어 있는 것 같습니다! 시간이 되신다면 테스트를 더 다양하게 만들어 보시는 것은 어떨까요? 테스트 커버리지를 확인하는 방법

//given
Car f1 = new Car("f1");
//when
f1.move(3);
//then
assertThat(f1.getPosition()).isEqualTo(0);
}
}