Skip to content

[LBP] 송하은 자동차 경주 미션 4단계 제출 #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: haeunsong
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ dependencies {
testImplementation platform('org.assertj:assertj-bom:3.25.1')
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.assertj:assertj-core')
testImplementation 'org.mockito:mockito-core:5.7.0'
testImplementation 'org.mockito:mockito-junit-jupiter:5.7.0'
}

test {
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/RacingGameApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import domain.RacingGame;
import view.InputView;
import view.ResultView;

public class RacingGameApplication {

public static void main(String[] args) throws Exception {
final var carNames = InputView.getCarNames();
final var tryCount = InputView.getRaceRounds();

final var racingGame = new RacingGame(carNames, tryCount);
Comment on lines +7 to +11

Choose a reason for hiding this comment

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

타입 추론을 사용하신 이유가 있나요?

racingGame.gameStart();

ResultView.printWinners(racingGame.getWinner());
}
}
27 changes: 27 additions & 0 deletions src/main/java/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package domain;

public class Car {

private final String name;
private int position;
private static final int MOVE_TRIGGER = 4;
Comment on lines +3 to +7

Choose a reason for hiding this comment

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

랜덤 생성은 분리가 되어 있으나,
4 이상의 숫자가 들어와야 이동한다는 것을 알고 있는 것 같아요.

그냥 이동하면 1칸 움직이게 만드는 것은 어떨까요? 이것은 어떤 장점이 있을까요?


public Car(String name) {
this.name = name;
this.position = 0;
}

public void move(int value) {
if (value >= MOVE_TRIGGER) {
position++;
}
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}
}
76 changes: 76 additions & 0 deletions src/main/java/domain/RacingGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package domain;

import java.util.*;
import java.util.stream.Collectors;

public class RacingGame {

private final List<Car> cars;
private final int rounds;
private Random random;

public RacingGame(String[] carsName, int rounds) {
this.cars = createCars(carsName);
this.rounds = rounds;
}

public RacingGame(List<Car> cars, int rounds) {
this.cars = cars;
this.rounds = rounds;
}

public RacingGame(String[] carsName, int rounds, Random random) {
this.cars = createCars(carsName);
this.rounds = rounds;
this.random = random;
}

public List<Car> getCars() {
return cars;
}

private List<Car> createCars(String[] carNames) {
List<Car> cars = new ArrayList<>();
for (String name : carNames) {
cars.add(new Car(name.trim()));
}
return cars;
}
Comment on lines +32 to +38

Choose a reason for hiding this comment

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

cars를 반환받고, 새로운 요소를 추가하려고 하면 추가될까요?

List<Car> cars = createCars(carNames);
cars.add(new Car()); // 가능할까요?

Choose a reason for hiding this comment

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

가능하다면 무슨 문제가 발생할 수 있을까요?


public void gameStart() {
for (int i = 0; i < rounds; i++) {
moveCars();
System.out.println();
}
}

private void moveCars() {
for (Car car : cars) {
System.out.print(car.getName() + " : ");
int randomValue = random.nextInt(10);
car.move(randomValue);
System.out.print("-".repeat(car.getPosition()));
System.out.println();
}
}
Comment on lines +47 to +55

Choose a reason for hiding this comment

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

무작위 숫자를 만드는 곳을 분리하면 더 나아질 것 같아요.


public List<Car> getWinner() {
int maxPosition = getMaxPosition();
return cars.stream()
.filter(car -> car.getPosition() == maxPosition)
.collect(Collectors.toUnmodifiableList());
}
Comment on lines +57 to +62

Choose a reason for hiding this comment

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

참고하면 좋을 글을 소개해드릴게요! getter를 사용하는 대신 객체에 메시지를 보내자


private int getMaxPosition() {
return cars.stream()
.mapToInt(Car::getPosition)
.max()
.orElse(0);
}

public String findWinnerName(List<Car> winnerCars) {
return winnerCars.stream()
.map(car -> car.getName())
.collect(Collectors.joining(", "));
}
}
45 changes: 45 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package view;

import java.util.Scanner;

public class InputView {

private static final int MAX_NAME_LENGTH = 5;

Choose a reason for hiding this comment

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

최대 이름 글자 수는 비즈니스 규칙 같은데, view가 알고 있어도 괜찮을까요?

private static final Scanner scanner = new Scanner(System.in);

private static String getUserInput() {
System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).");
return scanner.nextLine();
}

private static String[] splitCarNames(String inputValue) {
return inputValue.split(",");
}
Comment on lines +15 to +17

Choose a reason for hiding this comment

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

단순히 ,로 split 하는 기능을 수행하는 것 같아요.
해당 메서드에서 CarNames를 split한다고 꼭 알고 있어야 할까요?


public static String[] getCarNames() throws Exception {
String inputValue = getUserInput();
String[] carsName = splitCarNames(inputValue);

validateName(carsName);
return carsName;
}

private static void validateName(String[] carsName) throws Exception {
for (String carName : carsName) {
validateInput(carName);
}
}

public static void validateInput(String carName) throws Exception {
if (carName.length() > MAX_NAME_LENGTH) {
throw new Exception("자동차 이름은 " + MAX_NAME_LENGTH + "자 이하여야합니다.");
}
}

public static int getRaceRounds() {
System.out.println("시도할 회수는 몇회인가요?");
int rounds = scanner.nextInt();
System.out.println();
return rounds;
}
}
16 changes: 16 additions & 0 deletions src/main/java/view/ResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package view;

import domain.Car;

import java.util.List;

public class ResultView {

public static void printWinners(List<Car> winnerCars) {
System.out.println("실행 결과");
String winnerNames = String.join(", ",
winnerCars.stream().map(Car::getName).toArray(String[]::new)
);
System.out.println(winnerNames + "가 최종 우승했습니다.");
}
}
32 changes: 32 additions & 0 deletions src/test/java/domain/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package domain;

import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.*;

class CarTest {

@Test
void 자동차_생성_테스트() {
String inputNames = "haeun, minji, god";
String [] carNames = inputNames.split(", ");

RacingGame racingGame = new RacingGame(carNames,5);

List<Car> cars = racingGame.getCars();

assertThat(cars).hasSize(3);
}

@Test
void move_값이_4이상이면_전진한다() {
Car car = new Car("람보르기니");
car.move(5);
assertThat(1).isEqualTo(car.getPosition());

car.move(9);
assertThat(2).isEqualTo(car.getPosition());
}
Comment on lines +23 to +31

Choose a reason for hiding this comment

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

@ParameterizedTest를 학습하고 사용하면 더 나아질 것 같습니다.

}
53 changes: 53 additions & 0 deletions src/test/java/domain/RacingGameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package domain;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Random;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class RacingGameTest {

private RacingGame racingGame;
private Random mockRandom;

@BeforeEach
void setUp() {
mockRandom = mock(Random.class);
racingGame = new RacingGame(new String[]{"haeun", "ram", "com"}, 1, mockRandom);
}

@Test
void moveCars_랜덤값을_5로_고정하여_이동_테스트() {
when(mockRandom.nextInt(10)).thenReturn(5);

List<Car> cars = racingGame.getWinner();
int beforePosition = cars.get(0).getPosition();

cars.get(0).move(mockRandom.nextInt(10));
assertEquals(beforePosition + 1, cars.get(0).getPosition());
}

@Test
void get_winner_테스트() {

Car car1 = new Car("haeun");
Car car2 = new Car("ram");
Car car3 = new Car("com");

car1.move(3);
car2.move(9);
car2.move(5);
car3.move(5);
car3.move(9);

RacingGame game = new RacingGame(List.of(car1, car2, car3), 1);
List<Car> winners = game.getWinner();

assertTrue(winners.contains(car2));
assertTrue(winners.contains(car3));
}
Comment on lines +34 to +52

Choose a reason for hiding this comment

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

어떤 자동차가 몇번 움직였는지 파악하기 어려운 것 같아요.

  • 3, 9, 5, 5 라는 불규칙한 숫자
  • car1, car2 등 어떤 자동차인지 읽기 어려움 등

어떻게 개선할 수 있을까요?

}
21 changes: 21 additions & 0 deletions src/test/java/view/InputViewTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package view;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class InputViewTest {

@Test
void 자동차_이름_5자_넘으면_예외_발생_테스트() {
Exception exception = assertThrows(Exception.class, () -> {
InputView.validateInput("moremore");
});
assertEquals("자동차 이름은 5자 이하여야합니다.", exception.getMessage());
}

@Test
void 자동차_이름이_5자_이하면_예외가_발생하지_않는다() {
assertDoesNotThrow(() -> InputView.validateInput("haeun"));
assertDoesNotThrow(() -> InputView.validateInput("ram"));
}
}
27 changes: 27 additions & 0 deletions src/test/java/view/ResultViewTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package view;

import domain.Car;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class ResultViewTest {

@Test
void 우승자_이름을_올바르게_출력하는지_테스트() {
List<Car> winnerCars = List.of(
new Car("haeun"),
new Car("ram"),
new Car("com")
);

String expected = "haeun, ram, com";

assertEquals(expected, String.join(", ",
winnerCars.stream()
.map(Car::getName)
.toArray(String[]::new)));
}
}