Skip to content
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

Open
wants to merge 24 commits into
base: woogym
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7bcbdeb
docs: 구현할 기능 목록 추가
inhooo00 May 7, 2024
52d3e29
feat: 전체적인 코드 구현
inhooo00 May 9, 2024
06e9f84
[feat] Line 테스트코드 수정
woogym May 12, 2024
4b22a97
fix: InputView-readPlayerNames, LadderGameController createPlayersFro…
woogym May 19, 2024
4b1d3bb
docs: modified README.md
woogym May 19, 2024
c041f97
style: EOL code formating
woogym May 19, 2024
71237b4
fix: model/Ladder method therefore Controller, OutputView to
woogym May 19, 2024
3e02b65
fix: LadderTest.java TEST_GenerateLadder_OPERATION mothod
woogym May 19, 2024
6a303fb
fix: modifiy the ladder drawing part to OutputView responsibility
woogym May 19, 2024
77be39b
style: delete unused code in Ladder.java
woogym May 19, 2024
6277db2
fix: modify PlayerValidator method format
woogym May 20, 2024
cbb90a0
style: culf validator test class
woogym May 20, 2024
7078c7c
feature: getLines method
woogym May 20, 2024
01000e6
fix: modify generateLadder method test
woogym May 20, 2024
8d78464
fix: modify Height object create test method
woogym May 20, 2024
21762be
fix: makeLinewithNotFoothold test method
woogym May 20, 2024
5b180c0
fix: makeLineWithFoothold test method
woogym May 20, 2024
6672047
fix: Line.java makeLine mehtod
woogym May 20, 2024
a400f84
fix: overall LineTest test code
woogym May 20, 2024
be42958
style: modify test method naming
woogym May 20, 2024
f48250c
feature: LinesTest addLineTest method
woogym May 20, 2024
a210404
feature: LinesTest convertLinesToBooleanArrayTest method
woogym May 20, 2024
44bdede
style: modify overall test code method naming
woogym May 20, 2024
afef7f0
docs: modify README.md
woogym May 20, 2024
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
50 changes: 50 additions & 0 deletions docs/README.md
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차 리뷰 후 개선 방향

Choose a reason for hiding this comment

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

구현 기능 목록 👍

그런데, 몇몇 기능은 완성 못하신 건가요?

10 changes: 10 additions & 0 deletions src/main/java/Application.java
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();
}
}
57 changes: 57 additions & 0 deletions src/main/java/controller/LadderGameController.java
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(",");

Choose a reason for hiding this comment

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

split까지 InputView에서 해주면 어떨까요?

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;
}
}

Choose a reason for hiding this comment

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

EOL!

22 changes: 22 additions & 0 deletions src/main/java/exception/ErrorMessage.java
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;
}
}
47 changes: 47 additions & 0 deletions src/main/java/exception/LadderGameValidationException.java
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

Choose a reason for hiding this comment

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

Custom Exception을 구현하셨네요! Nested Class로 구현하신 특별한 이유가 있으실까요?

IllegalArgumentException으로 충분히 처리 가능한 것 같은데 Custom Exception을 구현한 이유는 무엇인가요?


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());
}
}

}
14 changes: 14 additions & 0 deletions src/main/java/model/Height.java
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;
}
}

Choose a reason for hiding this comment

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

EOL!

24 changes: 24 additions & 0 deletions src/main/java/model/Ladder.java
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();

Choose a reason for hiding this comment

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

StringBuilder를 생성자를 통해 필드에 주입할 이유가 있었나요?
makeLinesgenerateLadder 같은 이름으로 바꾸고 바로 return 해주는 편이 낫지 않았을까요?

클래스의 필드가 늘어났다는 것은 그만큼 의존하는 객체가 늘었다는 의미입니다!

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;
}
}

Choose a reason for hiding this comment

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

EOL!

19 changes: 19 additions & 0 deletions src/main/java/model/LadderSymbol.java
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;
}
}

Choose a reason for hiding this comment

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

model 패키지에 View와 깊게 관련된 코드가 있네요.

출력과 관련된 내용은 View 패키지에 있는 객체가 따로 처리해주는게 어떨까요?
BLANK일 경우 " "를 출력하도록 하는 방식으로요.

69 changes: 69 additions & 0 deletions src/main/java/model/Line.java
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;
}

Choose a reason for hiding this comment

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

Lint가 깨져있네요.. 제출 전에 SonarLint 플러그인을 활용해 검사해보거나
IntelliJ의 Save Action - Reformat Code 옵션을 활용해봅시다.


private void currentLadderLine(String ladderSymbol) {
line.append(ladderSymbol);
}

}
15 changes: 15 additions & 0 deletions src/main/java/model/Player.java
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;
}

}
26 changes: 26 additions & 0 deletions src/main/java/model/Players.java
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

Choose a reason for hiding this comment

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

일급 컬렉션 활용 👍

5 changes: 5 additions & 0 deletions src/main/java/util/FootholdGenerator.java
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

Choose a reason for hiding this comment

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

인터페이스 활용 👍
추상화를 적절히 사용하면 코드의 유연성이 높아집니다!

13 changes: 13 additions & 0 deletions src/main/java/util/RandomFootholdGenerator.java
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();
}
}
Loading