-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1단계 - 사다리 생성] 몰리(김지민) 미션 제출합니다. (#314)
* docs(README.md): 기능 요구사항 정리 * test(PersonTest): 이름 검증 로직 테스트 작성 * feat(Person): 이름 검증 로직 작성 * test(LineTest): 라인 검증 로직 테스트 작성 * feat(Line): 라인 검증 로직 작성 * test(PeopleTest): People 검증 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(People): People 검증 로직 작성 Co-authored-by: HaiSeong <[email protected]> * test(LadderTest): Ladder 검증 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(Ladder): Ladder 검증 로직 작성 Co-authored-by: HaiSeong <[email protected]> * test(LineTest): Line의 경로가 연달아 있지 않은지 검증하는 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(Line): 연달아 있지 않은 Line의 경로를 생성하는 로직 작성 Co-authored-by: HaiSeong <[email protected]> * test(NameParserTest): 입력받은 이름을 파싱하는 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(NameParser): 입력받은 이름을 파싱하는 로직 작성 - InputView 에 입력받은 텍스트를 파싱해 전달하는 메서드 작성 Co-authored-by: HaiSeong <[email protected]> * feat(InputView): 높이를 입력받는 로직 작성 Co-authored-by: HaiSeong <[email protected]> * test(NameFormatterTest): 형식에 맞춰 이름을 반환하는 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(NameFormatter): 형식에 맞춰 이름을 반환하는 로직 작성 Co-authored-by: HaiSeong <[email protected]> * test(LineFormatterTest): 형식에 맞춰 라인을 반환하는 기능 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(LineFormatter): 형식에 맞춰 라인을 반환하는 기능 작성 Co-authored-by: HaiSeong <[email protected]> * test(NamesFormatterTest): 형식에 맞춰 이름들을 반환하는 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * feat(NamesFormatter): 형식에 맞춰 이름들을 반환하는 로직 작성 Co-authored-by: HaiSeong <[email protected]> * feat(OutputView): 형식에 맞춰 실행결과를 출력하는 로직 작성 Co-authored-by: HaiSeong <[email protected]> * feat(InputView): 입력 문구 출력 추가 Co-authored-by: HaiSeong <[email protected]> * feat(Ladder, LadderTest): 사다리의 정적 팩토리 메서드에 인원수 인자 추가 Co-authored-by: HaiSeong <[email protected]> * refactor(LineTest): 연결 여부 변수명 교체 Co-authored-by: HaiSeong <[email protected]> * feat(Result, LineDto): 출력에 필요한 Dto 추가 Co-authored-by: HaiSeong <[email protected]> * feat(LadderGame, Application): 컨트롤러 작성 및 메인 메서드 추가 Co-authored-by: HaiSeong <[email protected]> * refactor(LineTest): 경로 존재 여부 원시값 포장 테스트 작성 Co-authored-by: HaiSeong <[email protected]> * refactor(Line, Path, LineInfo): 경로 존재 여부 원시값 포장 Co-authored-by: HaiSeong <[email protected]> * refactor(LineTest): 연달아 있는 사다리 테스트 로직 수정 Co-authored-by: HaiSeong <[email protected]> * style(PeopleTest, PersonTest, NamesFormatterTest): 필요없는 줄 제거 Co-authored-by: HaiSeong <[email protected]> * refactor(LineTest): 라인의 생성자로 값 리스트를 받도록 변경 Co-authored-by: HaiSeong <[email protected]> * refactor(Line): 라인의 생성자 변경, 검증로직 추가 Co-authored-by: HaiSeong <[email protected]> * refactor(LadderTest): 사다리 정적 팩토리 메서드 인자 변경 Co-authored-by: HaiSeong <[email protected]> * refactor(src): 메서드 및 변수에 final 키워드 추가 Co-authored-by: HaiSeong <[email protected]> * style(NameParserTest): 파일 끝에 개행 추가 * refactor(formatter): formatter의 패키지 위치를 view 아래로 이동 * refactor(Ladder): pathCount 변수 추출 * refactor(Line): 인원 수 검증이 아닌 경로의 사이즈로 검증 * fix(Line): 경로 검증 시 depth를 1으로 줄이기 위해 메서드 추출 * refactor(parser): 패키지 위치를 view 아래로 이동 * test(LadderTest): 사다리 생성에 대한 테스트 추가 * feat(FixedPathGenerator): 테스트를 위한 PathGenerator 구현체 생성 * feat(Line): equals 메서드 구현 * feat(Application): 예외 처리 추가 * style(PersonTest): 파일 끝에 개행 추가 --------- Co-authored-by: HaiSeong <[email protected]>
- Loading branch information
Showing
27 changed files
with
654 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
### 기능 요구사항 정리 | ||
- [x] 사람의 이름을 갖는다. | ||
- [x] 이름은 최소 1글자 최대 5글자다. | ||
- [x] 라인은 사다리의 가로 한줄을 의미한다. | ||
- [x] 한 라인은 사람수보다 하나 적은 폭을 갖는다. | ||
- [x] 사다리의 경로(path:가로라인)은 연달아 있을 수 없다. (나란히 있을 수 없다.) | ||
- [x] 참여할 사람의 이름은 쉼표로 구분해 받는다. | ||
- [x] 사람은 최소 2명 참가해야한다. | ||
- [x] 사다리의 높이를 입력받는다. | ||
- [x] 최소 높이는 1 이상이다. | ||
- [x] 실행 결과를 출력한다. | ||
- [x] 사다리를 출력한다. | ||
- [x] 라인의 첫 부분은 ` ` 4칸으로 출력한다. | ||
- [x] 5칸과 가장 오른쪽에 `|`를 높이만큼 출력한다. | ||
- [x] 라인에 경로가 있는 경우 `-`를 5칸을 출력한다. | ||
- [x] 라인에 경로가 없는 경우 ` `를 5칸을 출력한다. | ||
- [x] 이름을 출력한다. | ||
- [x] 이름이 4글자 이하인 경우, 오른쪽에 하나의 공백을 두고 우측 정렬한다. | ||
- [x] 이름이 5글자인 경우, 공백없이 우측 정렬한다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import controller.LadderGame; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
try { | ||
final LadderGame ladderGame = new LadderGame(new InputView(), new OutputView()); | ||
ladderGame.play(); | ||
} catch (Exception e) { | ||
System.out.println(e.getMessage()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package controller; | ||
|
||
import dto.Result; | ||
import java.util.List; | ||
import model.Ladder; | ||
import model.People; | ||
import model.path.RandomPathGenerator; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
public class LadderGame { | ||
private final InputView inputView; | ||
private final OutputView outputView; | ||
|
||
public LadderGame(final InputView inputView, final OutputView outputView) { | ||
this.inputView = inputView; | ||
this.outputView = outputView; | ||
} | ||
|
||
public void play() { | ||
final People people = initPeople(); | ||
final Ladder ladder = initLadder(people.getPersonCount()); | ||
|
||
final Result result = Result.from(people, ladder); | ||
outputView.printResult(result); | ||
} | ||
|
||
|
||
private People initPeople() { | ||
final List<String> names = inputView.inputNames(); | ||
return People.from(names); | ||
} | ||
|
||
private Ladder initLadder(final int personCount) { | ||
final int height = inputView.inputHeight(); | ||
return Ladder.from(height, personCount, new RandomPathGenerator()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package dto; | ||
|
||
import java.util.List; | ||
import model.Line; | ||
|
||
public record LineInfo(List<Boolean> lineInfo) { | ||
public static LineInfo from(final Line line) { | ||
final List<Boolean> lineInfo = line.getExistFlags(); | ||
return new LineInfo(lineInfo); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package dto; | ||
|
||
import java.util.List; | ||
import model.Ladder; | ||
import model.People; | ||
|
||
public record Result(List<String> names, List<LineInfo> lines) { | ||
public static Result from(final People people, final Ladder ladder) { | ||
final List<String> names = people.getNames(); | ||
final List<LineInfo> lines = ladder.getLines() | ||
.stream() | ||
.map(LineInfo::from) | ||
.toList(); | ||
|
||
return new Result(names, lines); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import model.path.PathGenerator; | ||
|
||
public class Ladder { | ||
private final List<Line> lines; | ||
|
||
private Ladder(final List<Line> lines) { | ||
this.lines = lines; | ||
} | ||
|
||
public static Ladder from(final int height, final int personCount, final PathGenerator pathGenerator) { | ||
validateHeight(height); | ||
final List<Line> lines = new ArrayList<>(); | ||
for (int i = 0; i < height; i++) { | ||
int pathCount = personCount - 1; | ||
final Line line = new Line(pathGenerator.generate(pathCount)); | ||
lines.add(line); | ||
} | ||
return new Ladder(lines); | ||
} | ||
|
||
private static void validateHeight(final int height) { | ||
if (height < 1) { | ||
throw new IllegalArgumentException("사다리의 높이는 1 이상이어야 합니다."); | ||
} | ||
} | ||
|
||
public List<Line> getLines() { | ||
return lines; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package model; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
import model.path.Path; | ||
|
||
public class Line { | ||
private static final int MIN_PATH_SIZE = 1; | ||
|
||
private final List<Path> paths; | ||
|
||
public Line(final List<Path> paths) { | ||
validatePathCount(paths.size()); | ||
checkContinuousPaths(paths); | ||
this.paths = paths; | ||
} | ||
|
||
private void validatePathCount(final int pathSize) { | ||
if (pathSize < MIN_PATH_SIZE) { | ||
throw new IllegalArgumentException("사다리의 경로는 비어있더라도 최소 1개 이상이여야 합니다."); | ||
} | ||
} | ||
|
||
private void checkContinuousPaths(final List<Path> paths) { | ||
for (int i = 0; i < paths.size() - 1; i++) { | ||
final Path left = paths.get(i); | ||
final Path right = paths.get(i + 1); | ||
validateContinuousPaths(left, right); | ||
} | ||
} | ||
|
||
private void validateContinuousPaths(final Path left, final Path right) { | ||
if (left == Path.EXIST && right == Path.EXIST) { | ||
throw new IllegalArgumentException("사다리의 경로는 연달아 있을 수 없습니다."); | ||
} | ||
} | ||
|
||
public List<Boolean> getExistFlags() { | ||
return paths.stream() | ||
.map(Path::isExist) | ||
.toList(); | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Line line = (Line) o; | ||
return Objects.equals(paths, line.paths); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package model; | ||
|
||
import java.util.List; | ||
|
||
public class People { | ||
private static final int MIN_PERSON_COUNT = 2; | ||
|
||
private final List<Person> personGroup; | ||
|
||
private People(final List<Person> personGroup) { | ||
validatePersonCount(personGroup.size()); | ||
this.personGroup = personGroup; | ||
} | ||
|
||
private void validatePersonCount(final int personCount) { | ||
if (personCount < MIN_PERSON_COUNT) { | ||
throw new IllegalArgumentException("사람은 최소 2명 참가해야 합니다."); | ||
} | ||
} | ||
|
||
public static People from(final List<String> names) { | ||
final List<Person> personGroup = names.stream() | ||
.map(Person::new) | ||
.toList(); | ||
return new People(personGroup); | ||
} | ||
|
||
public List<String> getNames() { | ||
return personGroup.stream() | ||
.map(Person::getName) | ||
.toList(); | ||
} | ||
|
||
public int getPersonCount() { | ||
return personGroup.size(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package model; | ||
|
||
public class Person { | ||
private static final int MIN_NAME_LENGTH = 1; | ||
private static final int MAX_NAME_LENGTH = 5; | ||
|
||
private final String name; | ||
|
||
public Person(final String name) { | ||
validateNameLength(name); | ||
this.name = name; | ||
} | ||
|
||
private void validateNameLength(final String name) { | ||
final int length = name.length(); | ||
if (length < MIN_NAME_LENGTH || length > MAX_NAME_LENGTH) { | ||
throw new IllegalArgumentException("이름은 최소 1글자 최대 5글자여야 합니다."); | ||
} | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package model.path; | ||
|
||
import java.util.List; | ||
|
||
public class FixedPathGenerator implements PathGenerator { | ||
private final List<Path> lines; | ||
|
||
public FixedPathGenerator(final List<Path> lines) { | ||
this.lines = lines; | ||
} | ||
|
||
@Override | ||
public List<Path> generate(final int count) { | ||
return this.lines; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package model.path; | ||
|
||
public enum Path { | ||
EXIST(true), | ||
NOT_EXIST(false); | ||
|
||
private final boolean isExist; | ||
|
||
Path(final boolean isExist) { | ||
this.isExist = isExist; | ||
} | ||
|
||
public boolean isExist() { | ||
return isExist; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package model.path; | ||
|
||
import java.util.List; | ||
|
||
public interface PathGenerator { | ||
List<Path> generate(final int count); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package model.path; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
public class RandomPathGenerator implements PathGenerator { | ||
private final Random random = new Random(); | ||
|
||
@Override | ||
public List<Path> generate(final int count) { | ||
final List<Path> paths = new ArrayList<>(); | ||
while (paths.size() < count) { | ||
Path randomPath = getNextPath(paths); | ||
paths.add(randomPath); | ||
} | ||
return paths; | ||
} | ||
|
||
private Path getNextPath(final List<Path> paths) { | ||
if (!paths.isEmpty() && getLastPath(paths) == Path.EXIST) { | ||
return Path.NOT_EXIST; | ||
} | ||
if (random.nextBoolean()) { | ||
return Path.EXIST; | ||
} | ||
return Path.NOT_EXIST; | ||
} | ||
|
||
private Path getLastPath(final List<Path> paths) { | ||
return paths.get(paths.size() - 1); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package view; | ||
|
||
import java.util.List; | ||
import java.util.Scanner; | ||
import view.parser.NameParser; | ||
|
||
public class InputView { | ||
private final Scanner scanner = new Scanner(System.in); | ||
|
||
public List<String> inputNames() { | ||
System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); | ||
final String text = scanner.next(); | ||
return NameParser.parse(text); | ||
} | ||
|
||
public int inputHeight() { | ||
System.out.println(); | ||
System.out.println("최대 사다리 높이는 몇 개인가요?"); | ||
return scanner.nextInt(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package view; | ||
|
||
import dto.LineInfo; | ||
import dto.Result; | ||
import view.formatter.LineFormatter; | ||
import view.formatter.NamesFormatter; | ||
import java.util.List; | ||
|
||
public class OutputView { | ||
|
||
public void printResult(final Result result) { | ||
System.out.println(); | ||
System.out.println("실행결과"); | ||
System.out.println(); | ||
final List<String> names = result.names(); | ||
printNames(names); | ||
printLines(result.lines()); | ||
} | ||
|
||
public void printNames(final List<String> names) { | ||
System.out.println(NamesFormatter.format(names)); | ||
} | ||
|
||
public void printLines(final List<LineInfo> lines) { | ||
lines.forEach(this::printLine); | ||
} | ||
|
||
private void printLine(final LineInfo line) { | ||
final List<Boolean> paths = line.lineInfo(); | ||
System.out.println(LineFormatter.format(paths)); | ||
} | ||
} |
Oops, something went wrong.