-
Notifications
You must be signed in to change notification settings - Fork 442
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
[자동자 경주 게임] 이준섭 미션 제출합니다. #533
base: main
Are you sure you want to change the base?
Changes from 7 commits
4c9b5bd
1dd0320
778bd42
7e2027e
fc32731
8d54909
3d5d1ff
06548c0
5376620
cfa16f2
4a3b5bc
b696c3d
76d0c39
5839d31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,7 +1,120 @@ | ||||||
package racingcar; | ||||||
|
||||||
import camp.nextstep.edu.missionutils.Console; | ||||||
|
||||||
import java.util.*; | ||||||
|
||||||
public class Application { | ||||||
public static void main(String[] args) { | ||||||
// TODO 구현 진행 | ||||||
List<String> carNames = receiveCarNames(); | ||||||
|
||||||
List<Car> cars = createCars(carNames); | ||||||
|
||||||
int tryCount = receiveTryCount(); | ||||||
|
||||||
runRacingGame(cars, tryCount); | ||||||
|
||||||
printWinners(findWinners(cars)); | ||||||
} | ||||||
|
||||||
|
||||||
private static List<String> receiveCarNames() { | ||||||
List<String> carNames; | ||||||
while (true) { | ||||||
System.out.println("경주할 자동차 이름을 입력하세요. (이름은 쉼표(,) 기준으로 구분)"); | ||||||
String input = Console.readLine(); | ||||||
carNames = Arrays.asList(input.split(",", -1)); | ||||||
try { // 예외가 발생한다면? -> catch | ||||||
validateCarNames(carNames); // 유효성 검사 | ||||||
break; | ||||||
} | ||||||
catch (IllegalArgumentException e) { | ||||||
System.out.println("[ERROR] 올바른 형식의 자동차 이름을 입력하세요."); | ||||||
} | ||||||
} | ||||||
return carNames; | ||||||
} | ||||||
|
||||||
private static void validateCarNames(List<String> carNames) { | ||||||
for (String inputName : carNames) { | ||||||
if (inputName.isEmpty() || inputName.length() > 5) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
이렇게 클래스에 상수를 따로 선언해서 수정했을 때 어떤 이점이 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코드가 길고 복잡해졌을 때 숫자 5가 무엇을 나타내는지 혼동이 올 수 있습니다. |
||||||
throw new IllegalArgumentException(); | ||||||
} | ||||||
} | ||||||
Set<String> uniqueNames = new HashSet<>(carNames); // 중복을 허용하지 않는 자료구조 | ||||||
if (uniqueNames.size() < carNames.size()) { // 작다면 중복된 이름이 있다는 것을 의미함 | ||||||
throw new IllegalArgumentException(); | ||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 적절한 자료구조 활용💯 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HashSet은 중복을 허용하지 않는 집합을 나타내는 자료구조입니다. |
||||||
} | ||||||
|
||||||
private static int receiveTryCount() { | ||||||
int tryCount; | ||||||
while (true) { | ||||||
System.out.println("시도할 횟수는 몇 회인가요?"); | ||||||
String input = Console.readLine(); | ||||||
try { | ||||||
tryCount = Integer.parseInt(input); // 문자열을 정수로 변환하는 문법 | ||||||
validateTryCount(tryCount); | ||||||
break; | ||||||
} | ||||||
catch (IllegalArgumentException e) { | ||||||
System.out.println("[ERROR] 올바른 형식의 숫자를 입력하세요."); | ||||||
} | ||||||
} | ||||||
return tryCount; | ||||||
} | ||||||
|
||||||
private static void validateTryCount(int tryCount) { | ||||||
if (tryCount <= 0) { | ||||||
throw new IllegalArgumentException(); | ||||||
} | ||||||
} | ||||||
|
||||||
private static List<Car> createCars(List<String> carNames) { | ||||||
List<Car> cars = new ArrayList<>(); // 리스트 생성 후 리스트의 원소가 Car 클래스의 인스턴스가 되도록 | ||||||
for (String name : carNames) { | ||||||
cars.add(new Car(name)); | ||||||
} | ||||||
return cars; | ||||||
} | ||||||
|
||||||
private static void runRacingGame(List<Car> cars, int tryCount) { | ||||||
System.out.println("\n실행 결과"); | ||||||
for (int i = 0; i < tryCount; i++) { | ||||||
for (Car car : cars) { | ||||||
car.moveForward(); | ||||||
} | ||||||
printRoundResult(cars); | ||||||
} | ||||||
} | ||||||
|
||||||
private static void printRoundResult(List<Car> cars) { | ||||||
for (Car car : cars) { | ||||||
System.out.println(car.getName() + " : " + new String(new char[car.getPosition()]).replace('\0', '-')); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Car 클래스의 name 필드 접근 제어자를 private에서 public 으로 변경하면 다음과 같이 코드를 수정할 수 있습니다. 왜 필드를 private으로 사용해야할까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 멤버 변수로의 직접 접근은 좋지 않습니다. 객체 지향 프로그래밍의 원칙 중 하나인 캡슐화에 위배됩니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 왜 외부에서 직접 접근하면 안될까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 외부에서 직접 접근하는 메서드가 많아진다면 추후 클래스의 구성이나 구현을 변경할 때 수정이 어려워지기 때문입니다! |
||||||
} | ||||||
System.out.println(); | ||||||
} | ||||||
|
||||||
private static List<String> findWinners(List<Car> cars) { | ||||||
int maxPosition = getMaxPosition(cars); | ||||||
List<String> winners = new ArrayList<>(); | ||||||
for (Car car : cars) { | ||||||
if (car.getPosition() == maxPosition) { | ||||||
winners.add(car.getName()); | ||||||
} | ||||||
} | ||||||
return winners; | ||||||
} | ||||||
|
||||||
private static int getMaxPosition(List<Car> cars) { | ||||||
int maxPosition = 0; | ||||||
for (Car car : cars) { | ||||||
maxPosition = Math.max(maxPosition, car.getPosition()); | ||||||
} | ||||||
return maxPosition; | ||||||
} | ||||||
|
||||||
private static void printWinners(List<String> winners) { | ||||||
System.out.println("최종 우승자 : " + String.join(", ", winners)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 적절한 함수활용 굿👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. String.join은 문자열을 결합할 때 사용합니다. |
||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,7 @@ | ||||||||||||||||
package racingcar; | ||||||||||||||||
|
||||||||||||||||
import camp.nextstep.edu.missionutils.Randoms; | ||||||||||||||||
|
||||||||||||||||
public class Car { | ||||||||||||||||
private final String name; | ||||||||||||||||
private int position = 0; | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
생성자 예시 public Car(String name) {
this.name = name;
this.position = 0;
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Integer 클래스는 int의 기능을 확장하여 여러 유용한 메서드를 제공합니다. 어떤 메서드들이 있을까?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 정리 좋네요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그렇군요! 멤버 변수는 생성자에서 초기화 하도록 해야겠습니다! |
||||||||||||||||
|
@@ -8,5 +10,18 @@ public Car(String name) { | |||||||||||||||
this.name = name; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
// 추가 기능 구현 | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 필요없는 주석삭제 👍👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 필요 없는 주석은 삭제! |
||||||||||||||||
public void moveForward() { | ||||||||||||||||
int randomValue = Randoms.pickNumberInRange(0,9); | ||||||||||||||||
if (randomValue >= 4) { | ||||||||||||||||
position++; | ||||||||||||||||
} | ||||||||||||||||
Comment on lines
+17
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 바꾸기 vs 그냥 쓰기
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 바꿨을 때의 장단점 장점: randomValue 변수를 사용한다면 코드를 읽기가 더 쉽습니다. 다른 부분에서 동일한 난수를 사용한다면 재사용에 용이합니다. 또한 난수 생성 로직이 변경되더라도 해당 부분만 수정하면 됩니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 정리 깔끔하네요! 그런데 매번 호출하는건 위 아래 전부 동일에서 성능은 사실상 동일합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다! 재사용할 수 있다는 것에 초점을 두고 이런 답변을 드렸네요! 현재 코드에서 성능은 동일합니다! |
||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
public String getName() { | ||||||||||||||||
return name; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
public int getPosition() { | ||||||||||||||||
return position; | ||||||||||||||||
} | ||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
자동차의 이름을 검사하는 기능은 Application 클래스의 책임일까요? 아니면 Car 클래스의 책임일까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
생각해보지 못한 내용입니다.
처음 봤을 때는 Application 클래스의 책임이라고 생각습니다. Car 객체는 정보만을 담고 있고 추가적인 기능들은 Application 단계에서 진행된다고 생각했기 때문입니다.
하지만 Car 클래스의 책임으로 간주되는 군요.
객체 지향 프로그래밍에서 각 클래스가 자체적으로 데이터를 처리해야하며 이어져 캡슐화하여 객체 데이터를 보호하는 것이 중요합니다.
Application 클래스는 전체 프로그램의 흐름을 제어하고, 사용자 입력을 처리하는 역할입니다.
자동차 이름을 입력 받은 후 Car 객체로 만드는 역할을 Application 에서 하며 Car 객체가 이름 유효성을 검사하도록 하면 이후 추가적인 클래스가 생겼을 때 각 클래스가 자신의 역할을 분담하고 유지보수와 확장에 용이합니다.