Skip to content

[사다리 타기 - 4단계] 리뷰 요청 드립니다. #886

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

Merged
merged 24 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7ba04b0
fix: 피드백: [SRP 규칙에 위반되는 Factory 클래스 수정](https://github.com/next-step/…
SeokRae Apr 9, 2021
c88f40a
fix: 피드백: [각 역할에 맞는 분리 및 입력 값에 대한 기본적인 가공(https://github.com/next-ste…
SeokRae Apr 9, 2021
59816dd
fix: 피드백: [각 역할에 맞는 분리 및 입력 값에 대한 기본적인 가공(https://github.com/next-ste…
SeokRae Apr 9, 2021
b0b571a
docs: 3단계 - 2차 피드백 정리
SeokRae Apr 9, 2021
4263e79
docs: 3단계 - 2차 피드백 정리
SeokRae Apr 9, 2021
ab20ee3
docs: 4단계 정리
SeokRae Apr 9, 2021
0f6ff26
feat: 4단계 요구사항 클래스 생성
SeokRae Apr 9, 2021
20483a0
refactor: Direction 도메인 관련 테스트 코드 수정
SeokRae Apr 9, 2021
6b1947d
refactor: Point 생성 및 좌우 이동 테스트
SeokRae Apr 9, 2021
92a830b
refactor: LadderLine 생성 확인
SeokRae Apr 9, 2021
6aa7ef0
refactor: step4에서 제공하는 클래스명 prefix Hint 추가 및 LadderLine 테스트
SeokRae Apr 9, 2021
7d611b2
refactor: HintLadderLine 테스트 수정
SeokRae Apr 9, 2021
9d86f35
refactor: 리터럴 문자 상수 처리
SeokRae Apr 10, 2021
e035726
refactor: 출력 코드 제거
SeokRae Apr 10, 2021
9fb6eae
refactor: 사다리 출력 조건을 위한 isLeft 메서드 추가
SeokRae Apr 10, 2021
1dcb50d
refactor: HintLadderLine 결과 값 출력을 위한 리스트 메서드 추가
SeokRae Apr 10, 2021
e39c939
refactor: 불변(final 처리) 또는 가변 파라미터 값 구분
SeokRae Apr 10, 2021
32223ce
refactor: HintLadder 사다리 생성 및 사다리 타기 테스트
SeokRae Apr 10, 2021
5140323
refactor: position에 대한 공통 처리를 위해 int 사용
SeokRae Apr 10, 2021
ab8f656
refactor: LadderRewards 클래스의 보상 값 위치확인 테스트
SeokRae Apr 10, 2021
04566b4
refactor: 생성자의 접근 제한자 수정
SeokRae Apr 10, 2021
651203c
refactor: 힌트로 주어진 클래스의 사다리 보상 메서드 추가
SeokRae Apr 10, 2021
4d16a50
refactor: 힌트 로직 타기 위해서 신규 메서드 작성?
SeokRae Apr 10, 2021
2734af6
refactor: 피드백: [사다리 타기 로직에 대한 책임이 있는 객체는 어디?](https://github.com/next…
SeokRae Apr 11, 2021
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
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,15 @@ false | false | true |

![Ladder Step3 Feedback Diagram](docs/ladder3_1.png)


> 사다리 타기 3단계 2차 피드백

- [x] [전략 패턴에 대한 이슈](https://github.com/next-step/java-ladder/pull/859#discussion_r609632110)
- [x] [SRP 규칙 위반](https://github.com/next-step/java-ladder/pull/859#discussion_r609641620)
- [x] [과연 필요한 클래스인가?](https://github.com/next-step/java-ladder/pull/859#discussion_r609644819)

![Ladder Step3 Feedback2 Diagram](docs/ladder3_2.png)

## 사다리 타기 피드백
- Ladder를 작은 단위로 쪼갠다.
- Line (List<Point>)
Expand All @@ -241,3 +250,21 @@ false | false | true |

- Cyclic dependency 를 해결하는 방법
- FactoryBean 역할을 하는 클래스를 만들어야 한다.

## 4단계 - 사다리(리팩토링)

- 기능 요구사항
- 기능 요구사항 3단계와 같다.
- 추가로 제공되는 객체 설계 힌트를 참고해 철저하게 TDD로 재구현해 본다.

- 객체 추출 힌트
- 사다리 한 Line 추상화
- 사다리 게임에서 한 Line을 LadderLine으로 이름을 붙이고 다음과 같이 구현
- 사다리 Line의 모든 Point 초기화와 이동을 담당

- LadderLine의 두 점과 현재 위치를 Point로 추상화
- LadderLine에서 위치와 각 점의 방향을 관리

- 각 Point의 좌/우 방향을 Direction으로 추상화
- 각 Point의 좌/우 방향 정보를 가진다.
- 현재 Point에서 다음 Point를 생성하는 역할
Binary file added docs/ladder3_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/main/java/nextstep/ladder/LadderRideApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ public static void main(String[] args) {
ResultView resultView = new ResultView();

LadderGameController ladderGameController = new LadderGameController(inputView, resultView);
ladderGameController.start();
ladderGameController.hintStart();
}
}
125 changes: 106 additions & 19 deletions src/main/java/nextstep/ladder/controller/LadderGameController.java
Original file line number Diff line number Diff line change
@@ -1,49 +1,136 @@
package nextstep.ladder.controller;

import nextstep.ladder.domain.Height;
import nextstep.ladder.domain.Position;
import nextstep.ladder.domain.Reward;
import nextstep.ladder.domain.User;
import nextstep.ladder.generator.DefaultLineGenerator;
import nextstep.ladder.generator.LineGenerator;
import nextstep.ladder.service.LadderFactory;
import nextstep.ladder.domain.*;
import nextstep.ladder.hint.HintLadder;
import nextstep.ladder.service.Ladder;
import nextstep.ladder.service.LadderResult;
import nextstep.ladder.service.LadderRewards;
import nextstep.ladder.service.Participants;
import nextstep.ladder.view.InputView;
import nextstep.ladder.view.ResultView;
import nextstep.ladder.wrapper.*;

import static nextstep.ladder.controller.LadderParameterHelper.parseArgumentResolver;
import java.util.*;

public class LadderGameController {

private static final String GUIDE_ERR_NOT_EQUALS_SIZE = "참여자 수에 일치하는 결과 값을 입력해야 합니다.";
private static final String GUIDE_ERR_INPUT_DATA = "입력 값이 없습니다.";
private static final String SPLIT_DELIMITER = ",";

public static final String GUIDE_LADDER_END_SIGNATURE = "all";
private final LadderParameterProcessor processor;
private final InputView inputView;
private final ResultView resultView;
private final LineGenerator generator;
private final LineGenerator generator = new DefaultLineGenerator();

public LadderGameController(final InputView inputView, final ResultView resultView) {
this(new LadderParameterProcessor(inputView), resultView, new DefaultLineGenerator());
}

public LadderGameController(final LadderParameterProcessor processor, final ResultView resultView, final LineGenerator generator) {
this.processor = processor;
this.inputView = inputView;
this.resultView = resultView;
this.generator = generator;
}

public void start() {
Participants participants = parseArgumentResolver(processor::processUsers);
LadderRewards rewards =
parseArgumentResolver(() -> processor.processLadderRewards(participants.size()));
Height height = parseArgumentResolver(processor::processHeight);
Participants participants = inputParticipants();
LadderRewards rewards = inputRewards(participants.size());
Height height = inputHeight();

Ladder ladder = LadderFactory.valueOf(participants, height, generator);
LadderResult ladderResult = LadderFactory.rideLadder(participants, ladder, rewards);
Ladder ladder = Ladder.valueOf(participants, height, generator);
LadderResult ladderResult = rideLadder(participants, ladder, rewards);

resultView.printResult(ladder, participants, rewards);

String user;
do {
user = parseArgumentResolver(processor::inputUserResult);
user = inputUserResult();
} while (!isOneOrAll(ladderResult, user));
}

public void hintStart() {
Participants participants = inputParticipants();
LadderRewards rewards = inputRewards(participants.size());
Height height = inputHeight();

HintLadder hintLadder = HintLadder.valueOf(participants, height);
LadderResult ladderResult = rideLadder(participants, hintLadder, rewards);

resultView.printResult(hintLadder, participants, rewards);

String user;
do {
user = inputUserResult();
} while (!isOneOrAll(ladderResult, user));
}

public LadderResult rideLadder(
final Participants participants, final Ladder ladder, final LadderRewards ladderRewards) {

Map<User, Reward> result = new LinkedHashMap<>();
Set<User> users = participants.getUsers();

for (User user : users) {
Position rewardPosition = ladder.findEndPosition(user.position());
Reward reward = ladderRewards.findReward(rewardPosition.currentPosition());
result.put(user, reward);
}

return LadderResult.valueOf(result);
}
private LadderResult rideLadder(Participants participants, HintLadder hintLadder, LadderRewards rewards) {
Map<User, Reward> result = new LinkedHashMap<>();
Set<User> users = participants.getUsers();

for (User user : users) {

int movePosition = user.position().currentPosition();
int rewardPosition = hintLadder.findEndPosition(movePosition);
Reward reward = rewards.findReward(rewardPosition);
result.put(user, reward);
}

return LadderResult.valueOf(result);
}

private Participants inputParticipants() {
String participants = inputView.inputParticipants();
checkNullOrEmpty(participants);
return Participants.valueOf(parseStringToArrays(participants));
}

private LadderRewards inputRewards(final int participantSize) {
String[] ladderRewards = parseStringToArrays(inputView.inputLadderRewards());
if(ladderRewards.length != participantSize) {
throw new IllegalArgumentException(GUIDE_ERR_NOT_EQUALS_SIZE);
}
return LadderRewards.valueOf(ladderRewards);
}

private Height inputHeight() {
String ladderHeight = inputView.inputLadderHeight();
checkNullOrEmpty(ladderHeight);
return Height.valueOf(Integer.parseInt(ladderHeight));
}

private String inputUserResult() {
String userResult = inputView.inputUserResult();
checkNullOrEmpty(userResult);
return userResult;
}

private void checkNullOrEmpty(final String inputValue) {
if (Objects.isNull(inputValue) || inputValue.isEmpty()) {
throw new IllegalArgumentException(GUIDE_ERR_INPUT_DATA);
}
}

private String[] parseStringToArrays(final String words) {
return Arrays.stream(words.split(SPLIT_DELIMITER))
.map(String::trim)
.toArray(String[]::new);
}

private boolean isOneOrAll(final LadderResult ladderResult, final String user) {
if(user.equals(GUIDE_LADDER_END_SIGNATURE)) {
resultView.printUserResult(ladderResult.findAll());
Expand Down

This file was deleted.

This file was deleted.

4 changes: 3 additions & 1 deletion src/main/java/nextstep/ladder/domain/Bar.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import java.util.Objects;

import static java.lang.Boolean.FALSE;

public class Bar {

private static final Bar BAR = Bar.valueOf(false);
private static final Bar BAR = Bar.valueOf(FALSE);
public final boolean flag;

private Bar(final boolean flag) {
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/nextstep/ladder/domain/Height.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,29 @@ public class Height {

private static final String GUIDE_ERR_HEIGHT_LESS_THAN = "높이가 1보다 작을 수는 없습니다.";
private static final int MIN_HEIGHT = 1;
public static final String GUIDE_ERR_PARSE_TO_INTEGER = "숫자만 입력받을 수 있습니다.";

private final int value;

private Height(final int value) {
if(value < MIN_HEIGHT) {
throw new IllegalArgumentException(GUIDE_ERR_HEIGHT_LESS_THAN);
}
this.value = value;
}

public static Height valueOf(final int value) {
if(value < MIN_HEIGHT) {
throw new IllegalArgumentException(GUIDE_ERR_HEIGHT_LESS_THAN);
}
return new Height(value);
}

public static Height valueOf(final String value) {
try {
return new Height(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new IllegalArgumentException(GUIDE_ERR_PARSE_TO_INTEGER);
}
}

public int size() {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package nextstep.ladder.generator;

import nextstep.ladder.domain.Bar;
import nextstep.ladder.wrapper.Line;
import nextstep.ladder.service.Line;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/nextstep/ladder/generator/LineGenerator.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package nextstep.ladder.generator;

import nextstep.ladder.wrapper.Line;
import nextstep.ladder.service.Line;

@FunctionalInterface
public interface LineGenerator {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/nextstep/ladder/generator/RandomValueGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package nextstep.ladder.generator;

import java.util.Random;

public class RandomValueGenerator {
private static final Random random = new Random();

public static boolean generatePoint() {
return random.nextBoolean();
}
}
Loading