-
Notifications
You must be signed in to change notification settings - Fork 93
[자동차 경주] 제세형 미션 제출합니다. #72
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
Changes from all commits
dba01e6
a50b5a2
a6025cd
bf7f5bc
aaf8656
05187e8
c52bad4
21a4025
68b82f3
bfa2c82
e2294f8
8712467
f000439
aeead73
7e39939
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 |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import domain.Race; | ||
import view.InputView; | ||
import view.ResultView; | ||
|
||
public class Application { | ||
|
||
private static Race race; | ||
private static int round; | ||
public static void main(String[] args) { | ||
while(true){ | ||
if (getValiedNames()){ | ||
break; //5글자를 넘는 이름을 입력받는 경우 재시도 | ||
} | ||
} | ||
round = InputView.getTryCount(); | ||
runRace(); | ||
ResultView.printWinners(race.getWinner()); | ||
} | ||
|
||
private static boolean getValiedNames() { | ||
try{ | ||
race = new Race(InputView.getCarNames()); | ||
return true; | ||
}catch (IllegalArgumentException e){ | ||
System.out.println(e.getMessage()); | ||
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. 세형님은 Application 클래스를 컨트롤러로 사용하신 것 같아요 ! 컨트롤러에 시스템 아웃풋과 관련된 로직이 있어, 이 부분은 View로 옮기면 좋을 것 같아요 ! 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. 콘솔과 관련된 모든 로직은 View에서만 구현할 수 있게 수정해보겠습니다! |
||
} | ||
return false; | ||
} | ||
|
||
private static void runRace(){ | ||
System.out.println("domain.Race result"); | ||
race.runRace(round); | ||
Comment on lines
+30
to
+32
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. 여기도 동일합니다 ! 레이싱 결과를 출력하기 위한 View만 존재해야 하는지 등 생각해보면 좋을 것 같아요. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package domain; | ||
|
||
public class Car { | ||
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. a6025cd 커밋을 보니, 커밋 메시지까지 보니 삭제하신 의도가 좋았습니다 👍 |
||
private String name; | ||
private int location; | ||
|
||
public Car(String name) throws IllegalArgumentException { | ||
this.setName(name); | ||
this.location = 0; | ||
} | ||
|
||
//private 속성들에 대한 getter 및 setter | ||
public String getName() { | ||
return name; | ||
} | ||
public void setName(String name) throws IllegalArgumentException { | ||
if(name.length()>5){ | ||
throw new IllegalArgumentException("name is must be less than 5 characters"); | ||
} | ||
this.name = name; | ||
} | ||
public int getLocation() { | ||
return location; | ||
} | ||
|
||
//랜덤으로 speed 값을 생성하는 대신, speed를 파라미터로 입력받아 자동차를 이동 | ||
public void move(int speed) throws IllegalArgumentException { | ||
if(speed > 9 || speed < 0){ | ||
throw new IllegalArgumentException("speed is must be between 0 and 9"); | ||
Comment on lines
+28
to
+29
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. 속도 예외 처리 굳굳 |
||
} | ||
this.location = calculateNextLocation(speed); | ||
|
||
} | ||
|
||
//speed값을 기준으로 다음 위치 계산 | ||
private int calculateNextLocation(int speed){ | ||
if(speed >= 4){ | ||
return this.location+1; | ||
} | ||
return this.location; | ||
} | ||
Comment on lines
+36
to
+41
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. 뎁스를 줄이기 위해 메소드로 추출한 부분 좋습니다 👍 |
||
|
||
|
||
|
||
|
||
|
||
Comment on lines
+42
to
+46
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. 개행 한 번 만 확인해주세요 ! |
||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,80 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
package domain; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.Random; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public class Race { | ||||||||||||||||||||||||||||||||||||||||||||||||||
final private List<Car> cars; | ||||||||||||||||||||||||||||||||||||||||||||||||||
private List<Car> winners; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//domain.Race 생성자 : ","를 이용해 구분하여 레이스에 참가하는 차량의 이름을 입력 | ||||||||||||||||||||||||||||||||||||||||||||||||||
public Race(String nameOfCars) throws IllegalArgumentException { | ||||||||||||||||||||||||||||||||||||||||||||||||||
String[] carNames = nameOfCars.split(","); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
cars = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
for (String carName : carNames) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cars.add(new Car(carName)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//getter | ||||||||||||||||||||||||||||||||||||||||||||||||||
public List<Car> getWinner() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
return winners; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//레이스 실행 | ||||||||||||||||||||||||||||||||||||||||||||||||||
public void runRace(int round){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
//주어진 횟수동안 이동 | ||||||||||||||||||||||||||||||||||||||||||||||||||
for(int i=0; i<round; i++){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
moveAllCars(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//승자 구하기 | ||||||||||||||||||||||||||||||||||||||||||||||||||
checkWinners(calcMaxLocation()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//모든 차량 이동 | ||||||||||||||||||||||||||||||||||||||||||||||||||
private void moveAllCars(){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
for(Car car: cars){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
car.move(new Random().nextInt(10)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
printCarProgress(car); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
System.out.println(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
private void printCarProgress(Car car){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+42
to
+46
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.
다양한 방법이 있겠지만, 레이싱을 한 번 수행한 후, 컨트롤러가 레이싱 현재 상황을 게터로 얻고, 뷰로 전달해서 출력하는 방법도 있을 것 같아요. 이를 위해서는 현재 컨트롤러에 있는 코드와 Race에 있는 코드를 많이 수정할 필요가 있지만, 하나를 배워간다는 점에서 좋은 의의가 있을 것 같아요 👍 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.print(car.getName() + " : "); | ||||||||||||||||||||||||||||||||||||||||||||||||||
for(int i = 0; i < car.getLocation(); i++){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
System.out.print("-"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
System.out.println(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//최대 거리 구하기 | ||||||||||||||||||||||||||||||||||||||||||||||||||
private int calcMaxLocation(){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
int maxLocation = -1; | ||||||||||||||||||||||||||||||||||||||||||||||||||
for(Car car:cars){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
maxLocation = Math.max(maxLocation, car.getLocation()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
return maxLocation; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//승자 구하기 | ||||||||||||||||||||||||||||||||||||||||||||||||||
private void checkWinners(int maxLocation){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
winners = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
for(Car car: cars){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
addWinners(car, maxLocation); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
//승자 추가하기 | ||||||||||||||||||||||||||||||||||||||||||||||||||
private void addWinners(Car car, int maxLocation){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
if(car.getLocation() == maxLocation){ | ||||||||||||||||||||||||||||||||||||||||||||||||||
winners.add(car); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+64
to
+78
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.
addWinners 메소드를 checkWinners로 변경 후 boolean을 반환하는 방식으로 변경하고, checkWinners 메소드를 addWinners로 변경 후 리스트에 넣는 방식을 사용한다면 메소드 명과 반환형을 일치시킬 수 있을 거 같다는 생각이 듭니다 !
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. 메서드 명명이 제일 어려운 것 같아요 😢 |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package view; | ||
|
||
import java.util.Scanner; | ||
|
||
public class InputView { | ||
private final static Scanner scanner = new Scanner(System.in); | ||
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 static String getCarNames(){ | ||
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. 뷰 관련 메소드를 static 메소드로 선언하신 이유가 궁금합니다 ! 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. 4단계 - 리펙터링 힌트에서 그런데 조금 찾아보니 객체 지향에서 정적 메서드가 갖는 단점이 몇가지 있는 것 같아요..! Mocking을 통한 테스트가 불가능 하다는 점과 다형성을 사용할 수 없는 단점이 있는 것 같습니다. 😨 굳이 static을 사용하지 않고도 Application 안에서 지역변수나 필드로 인스턴스화 하여 메서드 호출을 해도 문제가 없기 때문에 static을 사용하지 않는 쪽으로 수정하는게 좋을 것 같기도 합니다 👀 |
||
System.out.println("Enter names of cars which join the race (Names are separated by commas)"); | ||
return scanner.nextLine(); | ||
} | ||
|
||
public static int getTryCount(){ | ||
System.out.println("Enter rounds of race"); | ||
return scanner.nextInt(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package view; | ||
|
||
import domain.Car; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ResultView { | ||
public static void printWinners(List<Car> winners) { | ||
List<String> winnerNames = new ArrayList<>(); | ||
for (Car winner : winners) { | ||
winnerNames.add(winner.getName()); | ||
} | ||
Comment on lines
+10
to
+13
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. winners에 있는 Car의 name을 게터로 얻어서 출력을 한다면, view에서 리스트에 넣는 로직을 수행하지 않아도 될 것 같아요 ! |
||
String result = String.join(", ", winnerNames) + " is(are) winners"; | ||
System.out.println(result); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import domain.Car; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.Nested; | ||
|
||
import java.util.Random; | ||
|
||
import static org.assertj.core.api.Assertions.*; | ||
|
||
@DisplayName("움직이는 자동차 테스트") | ||
public class TestCar { | ||
|
||
@Nested | ||
@DisplayName("움직이는 자동차 기능테스트") | ||
class TestCarFeatures{ | ||
|
||
@Test | ||
@DisplayName("이동 테스트") | ||
void testMove(){ | ||
//given | ||
final Car testCar = new Car("test"); | ||
|
||
//when | ||
//자동차 이동시키기 | ||
int testSpeed = new Random().nextInt(10); | ||
testCar.move(testSpeed); | ||
|
||
//then | ||
if(testSpeed >= 4){ | ||
assertThat(1).isEqualTo(testCar.getLocation()); | ||
return; | ||
} | ||
assertThat(0).isEqualTo(testCar.getLocation()); | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayName("움직이는 자동차 예외테스트") | ||
class TestCarExceptions{ | ||
|
||
@Test | ||
@DisplayName("이동 예외 테스트") | ||
void testMoveException(){ | ||
//given | ||
final Car testCar = new Car("test"); | ||
|
||
//when | ||
assertThatThrownBy(()-> testCar.move(-1)).hasMessage("speed is must be between 0 and 9"); | ||
assertThatThrownBy(()-> testCar.move(10)).hasMessage("speed is must be between 0 and 9"); | ||
} | ||
|
||
@Test | ||
@DisplayName("차량 생성 예외 테스트") | ||
void testCarCreationException(){ | ||
assertThatThrownBy(()-> new Car("123456")).hasMessage("name is must be less than 5 characters"); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import domain.Race; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.Nested; | ||
|
||
import static org.assertj.core.api.Assertions.*; | ||
|
||
@DisplayName("자동차 경주 테스트") | ||
public class TestRace { | ||
|
||
@Nested | ||
@DisplayName("자동차 경주 기능 테스트") | ||
class TestRaceFeatures{ | ||
|
||
@Test | ||
@DisplayName("우승 자동차 구하기 테스트") | ||
void testRace(){ | ||
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. 테스트 코드에서는 내가 작성한 코드가 요구 사항을 만족 시켰는지, 코드를 수정한 이후 요구사항을 만족하고 있는지 확인하는 용도로도 사용할 수 있어요. 이 테스트 코드에서 요구 사항을 만족 시켰는 지 확인할 수 있는 방법은 조금 부족하다고 생각이 듭니다. 코드에서는 최소 거리를 이동한 사람이 우승하도록 작성하였지만, 주어진 요구사항은 최대 거리를 이동한 사람이 우승하는 것이라면 이 테스트에서는 이를 검증하기 힘들 것 같아요. 어떻게 하면 이를 입증할 수 있을까요?? 게터를 이용해서 레이싱에 참여하는 자동차에 move함수를 호출해서 임의로 이동 거리를 설정하는 방법도 있을 것 같아요 ! |
||
//given | ||
final Race testRace = new Race("test1,test2,test3"); | ||
|
||
//when | ||
//5회 동안 경주 | ||
testRace.runRace(5); | ||
|
||
//then | ||
assertThat(testRace.getWinner().get(0)).isNotNull(); | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayName("자동차 경주 예외 테스트") | ||
class TestRaceExceptions{ | ||
|
||
@Test | ||
@DisplayName("경주 생성 예외 테스트") | ||
void testRaceCreationException(){ | ||
assertThatThrownBy(() -> new Race("1234,12345,123456")).hasMessage("name is must be less than 5 characters"); | ||
} | ||
} | ||
} |
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.
재시도 로직 ! 저도 생각도 못해 본 부분이네요 👀
다음 같은 방법이 있을 것 같아요.
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.
do-while이 있었네요! 맨날 for, while만 쓰고 do-while은 정말 쓰는 케이스가 적어서 생각을 못했습니다 👍