Skip to content
3 changes: 2 additions & 1 deletion src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
GameManager gameManager = new GameManager();
gameManager.start();
}
}
15 changes: 15 additions & 0 deletions src/main/java/racingcar/AttemptReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;

public class AttemptReader {
public static int read() {
System.out.println("시도할 회수는 몇 회인가요?");
String inputNum = Console.readLine();
int attempts = Integer.parseInt(inputNum);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

숫자로 변환하지 못하는 경우의 방어 로직을 추가하면 좋을 거 같아요 !

if (attempts <= 0 ) {
throw new IllegalArgumentException ("0이상 입력하세요.");
}
return attempts;
}
}
30 changes: 30 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package racingcar;

public class Car implements Raceable{
private final String name;
private int distance = 0;
public Car (String name) {
validateName(name);
this.name = name;
}

private void validateName(String name){
if (name == null || name.isBlank() || name.length() > 5 || name.contains(" ")) {
throw new IllegalArgumentException ("올바른 값을 입력해주세요. (문자열을 입력하세요.)");
}
}

public void move(int randomNumber) {
if (randomNumber >= 4) {
distance ++;
}
}

public int getDistance() {
return distance;
}

public String getName() {
return name;
}
}
26 changes: 26 additions & 0 deletions src/main/java/racingcar/CarCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package racingcar;
import camp.nextstep.edu.missionutils.Console;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CarCreator {
public static List<Raceable> createCars() {
Comment on lines +8 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CarCreator 클래스명과 메소드 네이밍을 봤을 때는 자동차를 만드는 역할을 하는 것으로 예측이 가는데, 내부 로직은 사용자로부터 입력을 받는 로직도 있는 거 같아요 !
입력을 받는 부분을 별도의 클래스로 분리한다면, CarCreator는 자동차를 만드는 로직에만 집중을 할 수 있을 거 같아요 !

Comment on lines +8 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

추가로 반환값은 List으로 던지고 있어요. 여기서는 List로 던지고 받는 부분에서 List으로 받는다면, 클래스의 네이밍에 맞게 Car를 만들어서 주는 걸 명확하게 표현할 수 있을 거 같아요 !

System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
String inputName = Console.readLine();
String[] names = inputName.split(",");

Set<String> nameSet = new HashSet<>(List.of(names));
if (nameSet.size() != names.length) {
throw new IllegalArgumentException("중복된 값 입니다.");
}

List<Raceable> cars = new ArrayList<>();
for (String name : names) {
cars.add(new Car(name));
}

return cars;
}
}
24 changes: 24 additions & 0 deletions src/main/java/racingcar/GameManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar;

import camp.nextstep.edu.missionutils.Randoms;
import java.util.List;

public class GameManager {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DIP 원칙을 적용하면 start 내부 클래스에서 WiinerPicker와 같은 객체를 생성하는 책임을 가지지 않아도 될 거 같아요 1

public void start() {
List<Raceable> cars = CarCreator.createCars();
int attempts = AttemptReader.read();

System.out.println();
System.out.println("실행 결과");
for(int i = 1; i <= attempts; i++){
for (Raceable car : cars) {
int randomNumber = Randoms.pickNumberInRange(0, 9);
car.move(randomNumber);
System.out.println(car.getName() + " : " + "-".repeat(car.getDistance()));
}
System.out.println();
}
Comment on lines +13 to +20
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

GameManager이라는 클래스는 게임을 총괄하는 의미를 내포하고 있는 거 같은데, start 메소드에서는 게임 실행을 직접 관여하는 로직이 있는 거 같아요 ! 이를 별도의 클래스로 분리하는 건 어떨까요 ?

WinnerPicker winnerPicker = new WinnerPicker();
winnerPicker.printWinner(cars);
Comment on lines +21 to +22
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reader, Creator의 경우 static으로 선언하여 메소드를 호출했는데, WinnerPicker의 경우 메소드 내부에서 객체를 직접 생성하고 메소드를 호출하고 있습니다.

둘의 차이를 의도하신 부분이 있는지 국균님의 생각이 궁금합니다 👀

}
}
7 changes: 7 additions & 0 deletions src/main/java/racingcar/Raceable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar;

public interface Raceable {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

좋은 접근 방법인 거 같습니다 !
move에서는 해당 인터페이스를 구현하는 클래스의 이동 규칙을 모두 구현해야한다는 점에서 짚고 넘어가면 좋을 거 같아요. Car가 아닌 Bus도 있는데 Car와 이동 규칙이 동일하다면 ? Bus에서도 Car에 구현한 로직을 똑같이 구현해야하는 상황이 발생할 거 같아요.

중복을 최소화하면서 인터페이스의 이점을 가져갈 수 있는 방법을 고민해보시면 좋을 거 같습니다.

String getName();
int getDistance();
void move(int randomNumber);
}
23 changes: 23 additions & 0 deletions src/main/java/racingcar/WinnerPicker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package racingcar;

import java.util.ArrayList;
import java.util.List;

public class WinnerPicker {
public void printWinner(List<Raceable> cars) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

메소드에서 두개의 작업을 하고 있는 거 같아요.
출력만 하는 메소드에서 승자를 구하는 행위는 별도의 메소드로 분리해도 좋을 거 같습니다 !

int maxdistance = 0;
for (Raceable car : cars) {
if (car.getDistance() > maxdistance) {
maxdistance = car.getDistance();
}
}

List<String> winnercars = new ArrayList<>();
for (Raceable car : cars) {
if (car.getDistance() == maxdistance) {
winnercars.add(car.getName());
}
}
System.out.println("최종 우승자 : " + String.join(", ", winnercars));
}
}