-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1단계 사다리 생성] 다즐(최우창) 미션 제출합니다. (#70)
* docs: 기능 목록 작성 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 사람 이름 영문자 검증 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 사람 이름 길이 검증 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * docs: 요구사항 명세서 수정 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 플레이어 이름 앞, 뒤 공백 제거 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 플레이어 수 검증 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 플레이어 이름 중복 검증 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * chore: TDD 이후 클래스 위치 이동 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 특정 이동값을 가지는 방향 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 발판을 위한 숫자 생성 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 값에 알맞은 방향 반환 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 방향 생성 전략 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 방향들의 집합인 선 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 선 생성 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 사다리 생성 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 플레이어들의 이름 입력 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 최대 사다리 높이 입력 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 사다리 생성 결과 출력 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 높이 검증 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * refactor: 플레이어 이름 역할 분리 Co-authored-by: 70825 <hello70825@gmail.com> * feat: 사다리 애플리케이션 기능 구현 Co-authored-by: 70825 <hello70825@gmail.com> * refactor: 상수 추가 및 네이밍 수정 Co-authored-by: 70825 <hello70825@gmail.com> * refactor: 사다리 높이 역할 분리에 따른 리팩토링 Co-authored-by: 70825 <hello70825@gmail.com> * refactor: 네이밍 수정 및 불필요한 파라미터와 메서드 삭제 Co-authored-by: 70825 <hello70825@gmail.com> * refactor: 메서드 결합도와 복잡성을 높이는 메서드 전달자 제거 * refactor: 의미가 모호한 메서드명, 시그니처 수정 * refactor: 사다리 생성 역할 분리 * refactor: for -> while 사용하도록 수정 * refactor: 한번만 사용되는 예외 메시지인 경우 상수화 하지 않는 것으로 수정 * refactor: 공백이 포함되면 유효하지 않은 이름으로 처리하도록 수정 * refactor: format 비용을 고려하여 string 연산을 사용하도록 수정 * refactor: 의미있는 추상화를 위한 메서드명 수정 * refactor: 생성자에서 의존성 주입이 아닌 메서드에서 의존성 주입하도록 수정 * refactor: 라인 생성 메소드 재귀 -> while 방법으로 수정 * refactor: 발판에 대한 책임은 Direction이 가지도록 수정 * refactor: 출력 요구사항에 맞게 개행 추가 --------- Co-authored-by: 70825 <hello70825@gmail.com>
- Loading branch information
Showing
23 changed files
with
840 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
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 @@ | ||
package ladder; | ||
|
||
import java.util.Scanner; | ||
import ladder.controller.LadderController; | ||
import ladder.domain.generator.LadderGenerator; | ||
import ladder.view.InputView; | ||
import ladder.view.OutputView; | ||
|
||
public class LadderApplication { | ||
|
||
public static void main(String[] args) { | ||
final var inputView = new InputView(new Scanner(System.in)); | ||
final var outputView = new OutputView(); | ||
final var ladderGenerator = new LadderGenerator(); | ||
|
||
LadderController ladderController = new LadderController(inputView, outputView, ladderGenerator); | ||
ladderController.run(); | ||
} | ||
} |
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,41 @@ | ||
package ladder.controller; | ||
|
||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
import ladder.domain.Height; | ||
import ladder.domain.Ladder; | ||
import ladder.domain.Players; | ||
import ladder.domain.generator.LadderGenerator; | ||
import ladder.domain.generator.LineGenerator; | ||
import ladder.view.InputView; | ||
import ladder.view.OutputView; | ||
|
||
public class LadderController { | ||
|
||
private final InputView inputView; | ||
private final OutputView outputView; | ||
private final LadderGenerator ladderGenerator; | ||
|
||
public LadderController(final InputView inputView, final OutputView outputView, | ||
final LadderGenerator ladderGenerator) { | ||
this.inputView = inputView; | ||
this.outputView = outputView; | ||
this.ladderGenerator = ladderGenerator; | ||
} | ||
|
||
public void run() { | ||
final Players players = generate(inputView::readPlayerNames, Players::new); | ||
final Height height = generate(inputView::readHeight, Height::new); | ||
final Ladder ladder = ladderGenerator.generate(new LineGenerator(), players, height); | ||
outputView.printLadderResult(players, ladder); | ||
} | ||
|
||
private <T, R> R generate(final Supplier<T> supplier, final Function<T, R> function) { | ||
try { | ||
return function.apply(supplier.get()); | ||
} catch (IllegalArgumentException e) { | ||
outputView.printErrorMessage(e.getMessage()); | ||
return generate(supplier, function); | ||
} | ||
} | ||
} |
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 ladder.domain; | ||
|
||
import java.util.Arrays; | ||
|
||
public enum Direction { | ||
|
||
LEFT(-1, "-----"), | ||
STAY(0, " "), | ||
RIGHT(1, " "), | ||
; | ||
|
||
private final int move; | ||
private final String foothold; | ||
|
||
Direction(final int move, final String foothold) { | ||
this.move = move; | ||
this.foothold = foothold; | ||
} | ||
|
||
public static Direction from(final int value) { | ||
return Arrays.stream(Direction.values()) | ||
.filter(direction -> direction.getMove() == value) | ||
.findFirst() | ||
.orElseThrow(() -> new IllegalArgumentException("유효하지 않은 값입니다.")); | ||
} | ||
|
||
public int getMove() { | ||
return move; | ||
} | ||
|
||
public String getFoothold() { | ||
return foothold; | ||
} | ||
} |
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,33 @@ | ||
package ladder.domain; | ||
|
||
public class Height { | ||
|
||
private static final int MINIMUM_HEIGHT = 2; | ||
private static final int MAXIMUM_HEIGHT = 10; | ||
|
||
private final int value; | ||
|
||
public Height(final int value) { | ||
validate(value); | ||
this.value = value; | ||
} | ||
|
||
private void validate(final int value) { | ||
if (hasShort(value) || hasLong(value)) { | ||
throw new IllegalArgumentException("높이는 " + MINIMUM_HEIGHT + "이상, " + MAXIMUM_HEIGHT + "이하여야 합니다." | ||
+ " 현재 높이는 " + value + "입니다."); | ||
} | ||
} | ||
|
||
private boolean hasShort(final int value) { | ||
return value < MINIMUM_HEIGHT; | ||
} | ||
|
||
private boolean hasLong(final int value) { | ||
return MAXIMUM_HEIGHT < value; | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
} |
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,18 @@ | ||
package ladder.domain; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class Ladder { | ||
|
||
private final List<Line> lines; | ||
|
||
public Ladder(final List<Line> lines) { | ||
this.lines = lines; | ||
} | ||
|
||
public List<Line> getLines() { | ||
return Collections.unmodifiableList(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 ladder.domain; | ||
|
||
import java.util.List; | ||
|
||
public class Line { | ||
|
||
private final List<Direction> directions; | ||
|
||
public Line(final List<Direction> directions) { | ||
this.directions = directions; | ||
} | ||
|
||
public List<Direction> getDirections() { | ||
return directions; | ||
} | ||
} |
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,63 @@ | ||
package ladder.domain; | ||
|
||
import java.util.Objects; | ||
import java.util.regex.Pattern; | ||
|
||
public class Name { | ||
|
||
private static final Pattern NAME_FORMAT = Pattern.compile("[a-zA-Z]+"); | ||
private static final int NAME_MAX_LENGTH = 5; | ||
|
||
private final String value; | ||
|
||
public Name(final String value) { | ||
validate(value); | ||
this.value = value; | ||
} | ||
|
||
private void validate(final String value) { | ||
validateFormat(value); | ||
validateLength(value); | ||
} | ||
|
||
private void validateFormat(final String value) { | ||
if (isNotEnglish(value)) { | ||
throw new IllegalArgumentException("사람 이름은 영문자만 가능합니다. 현재 입력은 " + value + " 입니다."); | ||
} | ||
} | ||
|
||
private boolean isNotEnglish(final String value) { | ||
return !NAME_FORMAT.matcher(value).matches(); | ||
} | ||
|
||
private void validateLength(final String value) { | ||
if (hasExceedLength(value)) { | ||
throw new IllegalArgumentException("사람 이름은 " + NAME_MAX_LENGTH + "글자까지 가능합니다. 현재 입력은 " + value + " 입니다."); | ||
} | ||
} | ||
|
||
private boolean hasExceedLength(final String value) { | ||
return NAME_MAX_LENGTH < value.length(); | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final Name name = (Name) o; | ||
return Objects.equals(getValue(), name.getValue()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(getValue()); | ||
} | ||
} |
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,33 @@ | ||
package ladder.domain; | ||
|
||
import java.util.Objects; | ||
|
||
public class Player { | ||
|
||
private final Name name; | ||
|
||
public Player(final String value) { | ||
this.name = new Name(value); | ||
} | ||
|
||
public String getName() { | ||
return name.getValue(); | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final Player player = (Player) o; | ||
return Objects.equals(name, player.name); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(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,69 @@ | ||
package ladder.domain; | ||
|
||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
public class Players { | ||
|
||
private static final int MINIMUM_PLAYER_SIZE = 2; | ||
private static final int MAXIMUM_PLAYER_SIZE = 10; | ||
|
||
private final List<Player> players; | ||
|
||
public Players(final List<String> names) { | ||
final List<Player> players = generatePlayers(names); | ||
validate(players); | ||
this.players = players; | ||
} | ||
|
||
private List<Player> generatePlayers(final List<String> names) { | ||
return names.stream() | ||
.map(Player::new) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void validate(final List<Player> players) { | ||
validatePlayerSize(players); | ||
validateDuplicatePlayer(players); | ||
} | ||
|
||
private void validatePlayerSize(final List<Player> players) { | ||
if (hasSmallSize(players) || hasLargeSize(players)) { | ||
throw new IllegalArgumentException( | ||
"플레이어는 " + MINIMUM_PLAYER_SIZE + "명 이상, " + MAXIMUM_PLAYER_SIZE + "명 이하만 가능합니다." | ||
+ " 현재 입력한 플레이어 수는 " + players.size() + "명 입니다."); | ||
} | ||
} | ||
|
||
private boolean hasSmallSize(final List<Player> players) { | ||
return players.size() < MINIMUM_PLAYER_SIZE; | ||
} | ||
|
||
private boolean hasLargeSize(final List<Player> players) { | ||
return MAXIMUM_PLAYER_SIZE < players.size(); | ||
} | ||
|
||
private void validateDuplicatePlayer(final List<Player> players) { | ||
final Set<Player> uniquePlayers = new HashSet<>(players); | ||
|
||
if (isDuplicate(players, uniquePlayers)) { | ||
throw new IllegalArgumentException("플레이어 이름은 중복되면 안됩니다."); | ||
} | ||
} | ||
|
||
private boolean isDuplicate(final List<Player> players, final Set<Player> uniquePlayers) { | ||
return players.size() != uniquePlayers.size(); | ||
} | ||
|
||
public List<String> getPlayerNames() { | ||
return players.stream() | ||
.map(Player::getName) | ||
.collect(Collectors.toUnmodifiableList()); | ||
} | ||
|
||
public int size() { | ||
return players.size(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/ladder/domain/generator/DirectionGenerator.java
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,9 @@ | ||
package ladder.domain.generator; | ||
|
||
import ladder.domain.Direction; | ||
|
||
@FunctionalInterface | ||
public interface DirectionGenerator { | ||
|
||
Direction generate(); | ||
} |
Oops, something went wrong.