-
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
[사다리 타기] 김예은 미션 제출합니다. #2
base: main
Are you sure you want to change the base?
Changes from 25 commits
edc31fc
a454554
b367140
88b6b2b
a49921e
6afc0f5
0dd15bc
c393e56
065ab77
d48d812
2b1b138
b5a1dde
9ec9c84
f064504
df1619c
6b7e70d
e48df59
5a2720c
5326a52
4b112ad
314556b
2f6fbc8
59d40d4
5ad3bcb
d638722
6344529
7c2631b
af55f04
4751865
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,55 @@ | ||
## 기능 구현 목록 | ||
|
||
### Model | ||
- [x] 사다리 라인(`|-----|`) | ||
- [x] `true` 가로 작대기 있음 | ||
- [x] `false` 가로 작대기 없음 | ||
- [x] 사다리 maker | ||
- [x] Boolean을 한 줄 랜덤하게 생성 | ||
- [x] 랜덤 생성한 Boolean line을 가로라인이 이웃끼리 겹치지 않도록 조정 | ||
- [x] 사다리 높이 예외처리(0을 제외한 숫자만 가능) | ||
- [x] 사람 | ||
- [x] 입력조건 예외처리 | ||
- [x] 이름 리스트를 형식에 맞게 공백 넣어주기 | ||
|
||
### View | ||
#### 입력 조건 | ||
- [x] 사람 이름 입력하기 | ||
- [x] 최대 5글자 (사람 이름이 5글자 이하라면 공백문자로 채워줘야 함) | ||
- [x] 쉼표 기준으로 입력받기 | ||
- [x] 첫 번째 사람인 경우에, 이름이 5글자 이하여도 여백을 공백문자로 채우지 않음 | ||
- [x] 사다리 높이 입력받기 | ||
- [x] 숫자만 입력받기 (공백 or 문자가 입력될 경우 예외처리) | ||
|
||
#### 출력 조건 | ||
- [x] 이름이 5글자일 경우, 이름의 끝 글자를 기준으로 입력 받은 높이만큼 사다리의 세로 라인 출력 | ||
- [x] 이름이 5글자 이하인 경우, 이름의 끝 글자 + 공백문자를 기준으로 입력 받은 높이만큼 사다리의 세로 라인 출력 | ||
- [x] 사다리가 정상적으로 작동하려면 가로 라인이 겹치지 않게 하기(ex.`|-----|-----|`) | ||
- x] 사다리 라인(`|-----|`) | ||
- [x] `true` -> `-----|` | ||
- [x] `false` -> ` |` | ||
|
||
### Controller | ||
- [x] 사다리 타리 진행 | ||
|
||
--- | ||
# 요구사항 | ||
사다리 타기 미션 저장소 | ||
- 사다리 게임에 참여하는 사람의 이름을 최대 5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. | ||
- 사람 이름은 쉼표(,)를 기준으로 구분한다. | ||
- 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. | ||
- 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. | ||
- `|-----|-----|` 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. | ||
|
||
### 추가된 요구 사항 | ||
- 모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. 단, UI(System.out, System.in) 로직은 제외 | ||
- 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다. | ||
- UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다. | ||
- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. | ||
- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. | ||
- 배열 대신 컬렉션을 사용한다. | ||
- Java Enum을 적용한다. | ||
- 모든 원시 값과 문자열을 포장한다 | ||
- 줄여 쓰지 않는다(축약 금지). | ||
- 일급 컬렉션을 쓴다. | ||
- | ||
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 ladder; | ||
|
||
import ladder.controller.LadderController; | ||
import ladder.view.InputView; | ||
import ladder.view.ResultView; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) { | ||
LadderController ladderController = new LadderController(new InputView(), new ResultView()); | ||
ladderController.start(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package ladder.controller; | ||
|
||
import java.util.List; | ||
import ladder.model.LadderMaker; | ||
import ladder.model.ManipulationPeople; | ||
import ladder.model.PersonList; | ||
import ladder.view.InputView; | ||
import ladder.view.ResultView; | ||
|
||
public class LadderController { | ||
|
||
private final ResultView resultView; | ||
private final InputView inputView; | ||
private ManipulationPeople manipulationPeople; | ||
private LadderMaker ladderMaker; | ||
|
||
|
||
public LadderController(InputView inputview, ResultView resultView) { | ||
this.inputView = inputview; | ||
this.resultView = resultView; | ||
} | ||
|
||
public void start() { | ||
resultView.startMessage(); | ||
this.manipulationPeople = new ManipulationPeople(new PersonList(inputView.inputName()).getPeople()); | ||
|
||
resultView.ladderHeightMessage(); | ||
this.ladderMaker = new LadderMaker(inputView.inputLadderHeight()); | ||
|
||
resultView.resultMessage(); | ||
resultView.printPeople(manipulationPeople.getManipulationPeopleNames()); | ||
|
||
for (int i = 0; i < ladderMaker.getLadderHeight(); i++) { | ||
resultView.printLine(getFirstManipulationName(), getPeopleSize()); | ||
} | ||
} | ||
|
||
private List<Boolean> getPeopleSize() { | ||
return ladderMaker.makeLadder(manipulationPeople.getManipulationPeopleNames().size()); | ||
} | ||
|
||
private String getFirstManipulationName() { | ||
return manipulationPeople.getManipulationPeopleNames().get(0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package ladder.model; | ||
|
||
import java.util.List; | ||
import ladder.util.validator.LadderValidator; | ||
|
||
public class LadderMaker { | ||
|
||
private int ladderHeight; | ||
|
||
public LadderMaker(String ladderHeight) { | ||
LadderValidator.checkEmpty(ladderHeight); | ||
LadderValidator.checkLadderNumberStandard(ladderHeight); | ||
|
||
this.ladderHeight = Integer.parseInt(ladderHeight); | ||
} | ||
|
||
public int getLadderHeight() { | ||
return ladderHeight; | ||
} | ||
|
||
public List<Boolean> makeLadder(int personCount) { | ||
RandomBoolean randomBoolean = new RandomBoolean(); | ||
Line lines = new Line(randomBoolean.createRandomColumn(personCount)); | ||
return lines.getPoints(); | ||
} | ||
} | ||
Comment on lines
+6
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,30 @@ | ||
package ladder.model; | ||
|
||
import java.util.List; | ||
|
||
public class Line { | ||
|
||
private RandomBoolean randomBoolean = new RandomBoolean(); | ||
|
||
private List<Boolean> points; | ||
|
||
public Line (List<Boolean> randomColumn) { | ||
this.points = randomColumn; | ||
rearrange(points); | ||
} | ||
|
||
public List<Boolean> getPoints() { | ||
return points; | ||
} | ||
|
||
private void rearrange(List<Boolean> columns) { | ||
boolean previousColumn = false; | ||
for (int i = 0; i < columns.size(); i++) { | ||
boolean currentColum = columns.get(i); | ||
if (previousColumn == currentColum){ | ||
columns.set(i, false); | ||
} | ||
previousColumn = currentColum; | ||
} | ||
} | ||
} | ||
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. 컨벤션 상, 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. 요구 사항에도 적혀있지만 이번 미션에서는 indent(들여쓰기)를 1로 제한하고 있습니다. 힌트를 드리자면, 메소드 분리 혹은 로직 자체의 리팩토링이 방법이 될 수 있습니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ManipulationPeople { | ||
|
||
private static final int BLOCK_DIGIT = 6; | ||
private static final int MAX_NAME_DIGIT = 5; | ||
private final List<String> manipulationPeopleNames = new ArrayList<>(); | ||
|
||
public ManipulationPeople(List<Person> personList) { | ||
manipulateNames(personList); | ||
} | ||
|
||
public List<String> getManipulationPeopleNames() { | ||
return manipulationPeopleNames; | ||
} | ||
|
||
private void manipulateNames(List<Person> personList) { | ||
for (Person person : personList) { | ||
manipulationPeopleNames.add(manipulateNameBlank(person.getName())); | ||
} | ||
} | ||
|
||
private String manipulateNameBlank(String name) { | ||
int blankNumber = BLOCK_DIGIT - name.length(); | ||
StringBuilder manipultionName = new StringBuilder(); | ||
|
||
if (name.length() == MAX_NAME_DIGIT) { | ||
manipultionName.append(" "); | ||
} | ||
|
||
for (int i = 0; i < blankNumber - 1; i++) { | ||
manipultionName.append(" "); | ||
} | ||
manipultionName.append(name); | ||
|
||
if (name.length() != MAX_NAME_DIGIT) { | ||
manipultionName.append(" "); | ||
} | ||
return manipultionName.toString(); | ||
} | ||
} | ||
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,19 @@ | ||
package ladder.model; | ||
|
||
import ladder.util.validator.PersonValidator; | ||
|
||
public class Person { | ||
|
||
private String name; | ||
|
||
public Person(String name) { | ||
PersonValidator.checkEmpty(name); | ||
PersonValidator.checkOverRange(name); | ||
PersonValidator.checkSpace(name); | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import ladder.util.validator.PersonValidator; | ||
|
||
public class PersonList { | ||
|
||
private List<Person> people = new ArrayList<>(); | ||
|
||
public PersonList(String nameList) { | ||
PersonValidator.checkDuplicate(nameList); | ||
personNameInput(nameList); | ||
} | ||
|
||
public List<Person> getPeople(){ | ||
return Collections.unmodifiableList(people); | ||
} | ||
|
||
private void personNameInput(String nameList) { | ||
for (String personName : Arrays.asList(nameList.split(","))) { | ||
people.add(new Person(personName)); | ||
} | ||
} | ||
} | ||
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,20 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
public class RandomBoolean { | ||
public List<Boolean> createRandomColumn(int personCount) { | ||
List<Boolean> columns = new ArrayList<>(); | ||
for (int i = 0; i < personCount - 1; i++) { | ||
columns.add(getRandomBoolean()); | ||
} | ||
return columns; | ||
} | ||
|
||
private boolean getRandomBoolean() { | ||
Random random = new Random(); | ||
return random.nextBoolean(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package ladder.util; | ||
|
||
public enum ErrorMessage { | ||
|
||
INPUT_STRING_DUPLICATE("입력 값이 중복되었습니다."), | ||
INPUT_STRING_NOT_NULL(" null이 될 수 없습니다."), | ||
INPUT_PERSON_NAME_IS_INCORRECT("입력한 사람 이름이 올바르지 않습니다."), | ||
INPUT_STRING_BLANK("입력 값은 공백이 될 수 없습니다."), | ||
INPUT_LADDER_NUMBER("입력된 숫자가 조건에 맞지 않습니다."); | ||
public final String message; | ||
|
||
ErrorMessage(String message) { | ||
this.message = message; | ||
} | ||
} | ||
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,23 @@ | ||
package ladder.util.validator; | ||
|
||
import java.util.regex.Pattern; | ||
import ladder.util.ErrorMessage; | ||
|
||
public class LadderValidator { | ||
|
||
public static void checkEmpty(String input) { | ||
if (input == null) { | ||
throw new IllegalArgumentException(ErrorMessage.INPUT_STRING_NOT_NULL.message); | ||
} | ||
} | ||
|
||
public static void checkLadderNumberStandard(String input) { | ||
if (!isRightLadderNumber(input)) { | ||
throw new IllegalArgumentException(ErrorMessage.INPUT_LADDER_NUMBER.message); | ||
} | ||
} | ||
|
||
private static boolean isRightLadderNumber(String input) { | ||
return Pattern.matches("^[1-9]\\d*$", input); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package ladder.util.validator; | ||
|
||
import static ladder.util.ErrorMessage.INPUT_PERSON_NAME_IS_INCORRECT; | ||
import static ladder.util.ErrorMessage.INPUT_STRING_BLANK; | ||
import static ladder.util.ErrorMessage.INPUT_STRING_DUPLICATE; | ||
import static ladder.util.ErrorMessage.INPUT_STRING_NOT_NULL; | ||
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.
리팩토링을 해야 하는 건 아니고, 알아 두시면 좋을 것 같습니다. |
||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.regex.Pattern; | ||
|
||
public class PersonValidator { | ||
|
||
private static final int MAX_DIGIT_PERSON_NAME = 5; | ||
private static final int MIN_DIGIT_PERSON_NAME = 1; | ||
|
||
public static void checkOverRange(String input) { | ||
if (isOverRange(input) || isUnderRange(input)) { | ||
throw new IllegalArgumentException(INPUT_PERSON_NAME_IS_INCORRECT.message); | ||
} | ||
} | ||
|
||
public static void checkSpace(String input) { | ||
if (isSpace(input)) { | ||
throw new IllegalArgumentException(INPUT_STRING_BLANK.message); | ||
} | ||
} | ||
|
||
public static void checkEmpty(String input) { | ||
if (input == null) { | ||
throw new IllegalArgumentException(INPUT_STRING_NOT_NULL.message); | ||
} | ||
} | ||
|
||
public static void checkDuplicate(String input) { | ||
if (hasDuplicatePersonName(input)) { | ||
throw new IllegalArgumentException(INPUT_STRING_DUPLICATE.message); | ||
} | ||
} | ||
|
||
private static boolean isOverRange(String input) { | ||
return MAX_DIGIT_PERSON_NAME < input.length(); | ||
} | ||
|
||
private static boolean isUnderRange(String input) { | ||
return MIN_DIGIT_PERSON_NAME > input.length(); | ||
} | ||
|
||
private static boolean isSpace(String input) { | ||
return Pattern.matches("^\\s+$", input); | ||
} | ||
|
||
private static boolean hasDuplicatePersonName(String input) { | ||
List<String> allPersonNames = new ArrayList<>(Arrays.asList(input.split(","))); | ||
Set set = new HashSet(allPersonNames); | ||
|
||
return allPersonNames.size() != set.size(); | ||
} | ||
} |
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.
사소하지만 오타는 가독성을 해치곤 합니다. 다음부턴 신경써주세요! 😁