-
Notifications
You must be signed in to change notification settings - Fork 12
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
[사다리 타기] 김우진 미션 제출합니다. #8
base: woogym
Are you sure you want to change the base?
Changes from 3 commits
7bcbdeb
52d3e29
06e9f84
4b22a97
4b1d3bb
c041f97
71237b4
3e02b65
6a303fb
77be39b
6277db2
cbb90a0
7078c7c
01000e6
8d78464
21762be
5b180c0
6672047
a400f84
be42958
f48250c
a210404
44bdede
afef7f0
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,50 @@ | ||
# 구현할 기능 목록 | ||
|
||
## 입력 | ||
- [x] 사용자 이름 입력 | ||
- [ ] 쉼표로 구분 | ||
- [ ] 최대 5글자까지 가능 | ||
- [x] 사다리 높이 입력 | ||
- [ ] 자연수 | ||
|
||
|
||
## 출력 | ||
- [x] 실행 결과 | ||
- [ ] 첫번째 줄 : 사람 이름 | ||
- [ ] 그 아래 줄 : 사다리 그리기 | ||
|
||
## 기능 | ||
- [ ] 사람의 이름을 받고 , 기준으로 나누기. | ||
- [ ] 한 줄에 | 개수를 사람 이름 개수만큼 반환. | ||
- [ ] 랜덤 값 기능 구현 | ||
- [ ] 랜덤에 충족하면 ----- 그리기. | ||
- [ ] 한줄의 |에 ----- 연결선이 동시에 나오지 않게 | ||
- [ ] 테스트 코드 작성 | ||
|
||
|
||
## TDD 객체 명세서 | ||
- [x] Height | ||
- [x] 객체 생성 가능 | ||
- [ ] Ladder | ||
- [x] 객체 생성 가능 | ||
- [ ] 전체적인 값이 맞는지 확인 | ||
- [ ] Line | ||
- [x] 객체 생성 가능 | ||
- [ ] 예상되는 사다리 라인 문자열 | ||
- [x] Player | ||
- [x] 객체 생성 가능 | ||
- [x] Players | ||
- [x] 객체 생성 가능 | ||
- [x] util | ||
- [x] LadderHeightValidator | ||
- [x] 정상_입력 | ||
- [x] 정수가_아닌_입력 | ||
- [x] 음수_입력 | ||
- [x] 공백_입력 | ||
- [x] PlayerNamesValidator | ||
- [x] 정상_입력 | ||
- [x] 공백_포함 | ||
- [x] 공백 | ||
- [x] 이름_길이_초과 | ||
- [x] 중복_입력 | ||
# 1차 리뷰 후 개선 방향 | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import controller.LadderGameController; | ||
|
||
import java.io.IOException; | ||
|
||
public class Application { | ||
public static void main(String[] args) throws IOException { | ||
LadderGameController ladderGameController = new LadderGameController(); | ||
ladderGameController.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package controller; | ||
|
||
import model.Height; | ||
import model.Ladder; | ||
import model.Player; | ||
import model.Players; | ||
import util.RandomFootholdGenerator; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class LadderGameController { | ||
private final InputView inputView; | ||
private final OutputView outputView; | ||
|
||
public LadderGameController() { | ||
this.inputView = new InputView(); | ||
this.outputView = new OutputView(); | ||
} | ||
|
||
public void run() throws IOException { | ||
Players players = createPlayersFromInput(); | ||
List<String> playerNames = extractPlayerNames(players); | ||
Height height = createHeightFromInput(); | ||
Ladder ladder = createLadder(players, height); | ||
|
||
outputView.printResultSentence(ladder.getLines(), playerNames); | ||
} | ||
|
||
private Players createPlayersFromInput() throws IOException { | ||
String[] playerNamesArray = inputView.readPlayerNames().split(","); | ||
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 new Players(Arrays.asList(playerNamesArray)); | ||
} | ||
|
||
private List<String> extractPlayerNames(Players players) { | ||
return players.getPlayers().stream() | ||
.map(Player::getName) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private Height createHeightFromInput() throws IOException { | ||
return new Height(inputView.readLadderHeightNumber()); | ||
} | ||
|
||
private Ladder createLadder(Players players, Height height) { | ||
Ladder ladder = new Ladder(); | ||
|
||
ladder.makeLines(height, players); | ||
|
||
return ladder; | ||
} | ||
} | ||
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. EOL! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package exception; | ||
|
||
public enum ErrorMessage { | ||
|
||
DUPLICATED_CAR_NAME("참여자 이름이 중복될 수 없습니다."), | ||
NOT_ALLOW_BLANK("참여자 이름에 공백이 들어갈 수 없습니다."), | ||
NOT_ALLOW_EMPTY("참여자 입력 값이 비어있을수 없습니다."), | ||
INVALID_NAME_LENGTH("참여자의 이름은 5자 이하여야합니다."), | ||
NOT_NUMERIC("시도 횟수 입력은 숫자여야 합니다."), | ||
ONLY_NATURAL_NUMBER("시도 횟수는 자연수여야합니다"), | ||
NOT_ALLOW_ZERO("사다리 높이는 0이 될 수 없습니다"); | ||
|
||
private final String message; | ||
|
||
ErrorMessage(String message) { | ||
this.message = message; | ||
} | ||
|
||
public String getMessage() { | ||
return message; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package exception; | ||
|
||
public class LadderGameValidationException { | ||
|
||
public static class DuplicatedPlayerNameException extends IllegalArgumentException { | ||
public DuplicatedPlayerNameException() { | ||
super(ErrorMessage.DUPLICATED_CAR_NAME.getMessage()); | ||
} | ||
} | ||
Comment on lines
+5
to
+9
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. Custom Exception을 구현하셨네요! Nested Class로 구현하신 특별한 이유가 있으실까요?
|
||
|
||
public static class BlankPlayerNameException extends IllegalArgumentException { | ||
public BlankPlayerNameException() { | ||
super(ErrorMessage.NOT_ALLOW_BLANK.getMessage()); | ||
} | ||
} | ||
|
||
public static class NotAllowEmptyInputException extends IllegalArgumentException { | ||
public NotAllowEmptyInputException() { | ||
super(ErrorMessage.NOT_ALLOW_EMPTY.getMessage()); | ||
} | ||
} | ||
|
||
public static class InvalidPlayerNameLengthException extends IllegalArgumentException { | ||
public InvalidPlayerNameLengthException() { | ||
super(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); | ||
} | ||
} | ||
|
||
public static class NotNumericException extends IllegalArgumentException { | ||
public NotNumericException() { | ||
super(ErrorMessage.NOT_NUMERIC.getMessage()); | ||
} | ||
} | ||
|
||
public static class NotNaturalNumberException extends IllegalArgumentException { | ||
public NotNaturalNumberException() { | ||
super(ErrorMessage.ONLY_NATURAL_NUMBER.getMessage()); | ||
} | ||
} | ||
|
||
public static class NotAllowZeroNumberException extends IllegalArgumentException { | ||
public NotAllowZeroNumberException() { | ||
super(ErrorMessage.NOT_ALLOW_ZERO.getMessage()); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package model; | ||
|
||
public class Height { | ||
|
||
private final String height; | ||
|
||
public Height(final String height) { | ||
this.height = height; | ||
} | ||
|
||
public String getHeight() { | ||
return height; | ||
} | ||
} | ||
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. EOL! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package model; | ||
|
||
import util.RandomFootholdGenerator; | ||
|
||
public class Ladder { | ||
private final StringBuilder lines; | ||
private Line line; | ||
|
||
public Ladder() { | ||
this.lines = new StringBuilder(); | ||
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. StringBuilder를 생성자를 통해 필드에 주입할 이유가 있었나요? 클래스의 필드가 늘어났다는 것은 그만큼 의존하는 객체가 늘었다는 의미입니다! |
||
this.line = new Line(new RandomFootholdGenerator()); | ||
} | ||
|
||
public void makeLines(Height height, Players players) { | ||
for (int i = 0; i < Integer.parseInt(height.getHeight()); i++) { | ||
line.makeLine(players); | ||
lines.append(line.getLine()).append("\n"); | ||
} | ||
} | ||
|
||
public StringBuilder getLines() { | ||
return lines; | ||
} | ||
} | ||
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. EOL! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package model; | ||
|
||
|
||
public enum LadderSymbol { | ||
|
||
BLANK(" "), | ||
FOOTHOLD("-----"), | ||
BAR("|"); | ||
|
||
private final String symbol; | ||
|
||
LadderSymbol(final String symbol) { | ||
this.symbol = symbol; | ||
} | ||
|
||
public String getSymbol() { | ||
return this.symbol; | ||
} | ||
} | ||
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,69 @@ | ||
package model; | ||
|
||
import util.FootholdGenerator; | ||
import util.RandomFootholdGenerator; | ||
|
||
public class Line { | ||
private final StringBuilder line; | ||
private static final int LAST_PLAYER_OFFSET = 1; | ||
private static final String BLANK = LadderSymbol.BLANK.getSymbol(); | ||
private static final String BAR = LadderSymbol.BAR.getSymbol(); | ||
private static final String FOOTHOLD = LadderSymbol.FOOTHOLD.getSymbol(); | ||
private final FootholdGenerator footholdGenerator; | ||
|
||
public Line(FootholdGenerator footholdGenerator) { | ||
this.line = new StringBuilder(); | ||
this.footholdGenerator = footholdGenerator; | ||
} | ||
|
||
public void makeLine(Players players) { | ||
initializeLine(); | ||
|
||
boolean previousWasFoothold = false; | ||
int numOfPlayers = players.findNumberOfPlayers(); | ||
|
||
for (int i = 0; i < numOfPlayers; i++) { | ||
currentLadderLine(BAR); | ||
previousWasFoothold = tryAppendFootholdIfNotLastPlayer(i, numOfPlayers, previousWasFoothold); | ||
} | ||
} | ||
|
||
private boolean tryAppendFootholdIfNotLastPlayer(int currentPlayerIndex, int totalPlayers, boolean previousWasFoothold) { | ||
if (isNotLastPlayer(currentPlayerIndex, totalPlayers)) { | ||
return tryAppendFootholdReturningSuccess(previousWasFoothold); | ||
} | ||
|
||
return previousWasFoothold; | ||
} | ||
|
||
public StringBuilder getLine() { | ||
return line; | ||
} | ||
|
||
private void initializeLine() { | ||
line.delete(0, line.length()); | ||
|
||
currentLadderLine(BLANK); | ||
} | ||
|
||
private boolean isNotLastPlayer(int currentIndex, int totalPlayers) { | ||
return currentIndex < totalPlayers - LAST_PLAYER_OFFSET; | ||
} | ||
|
||
private boolean tryAppendFootholdReturningSuccess(boolean hasPreviousFoothold) { | ||
if (!hasPreviousFoothold && footholdGenerator.generate()) { | ||
currentLadderLine(FOOTHOLD); | ||
|
||
return true; | ||
} | ||
|
||
currentLadderLine(BLANK); | ||
|
||
return false; | ||
} | ||
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. Lint가 깨져있네요.. 제출 전에 SonarLint 플러그인을 활용해 검사해보거나 |
||
|
||
private void currentLadderLine(String ladderSymbol) { | ||
line.append(ladderSymbol); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package model; | ||
|
||
public class Player { | ||
|
||
private final String playerName; | ||
|
||
public Player(String playerName) { | ||
this.playerName = playerName; | ||
} | ||
|
||
public String getName() { | ||
return this.playerName; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package model; | ||
|
||
import java.util.List; | ||
|
||
public class Players { | ||
|
||
private final List<Player> players; | ||
|
||
public Players(List<String> playerNames) { | ||
this.players = makePlayers(playerNames); | ||
} | ||
|
||
public int findNumberOfPlayers() { | ||
return this.players.size(); | ||
} | ||
|
||
public List<Player> getPlayers() { | ||
return players; | ||
} | ||
|
||
private List<Player> makePlayers(final List<String> playerNames) { | ||
return playerNames.stream() | ||
.map(Player::new) | ||
.toList(); | ||
} | ||
} | ||
Comment on lines
+5
to
+26
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,5 @@ | ||
package util; | ||
|
||
public interface FootholdGenerator { | ||
boolean generate(); | ||
} | ||
Comment on lines
+3
to
+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. 인터페이스 활용 👍 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package util; | ||
|
||
import java.util.Random; | ||
|
||
public class RandomFootholdGenerator implements FootholdGenerator{ | ||
|
||
private static Random random = new Random(); | ||
|
||
@Override | ||
public boolean generate() { | ||
return random.nextBoolean(); | ||
} | ||
} |
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.
구현 기능 목록 👍
그런데, 몇몇 기능은 완성 못하신 건가요?