Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
edc31fc
docs : README 기능구현 목록 작성
yeeun0702 May 5, 2024
a454554
feat: InputView, ResultView 구현
yeeun0702 May 5, 2024
b367140
test: 사람 이름 5글자 이상 예외 처리
sojeong0202 May 5, 2024
88b6b2b
feat: 사람 이름 5글자 이상 예외 처리 구현
sojeong0202 May 5, 2024
a49921e
test: 사람 이름 예외 처리 테스트 구현
sojeong0202 May 5, 2024
6afc0f5
feat: 사람 이름 예외 처리 구현
sojeong0202 May 5, 2024
0dd15bc
feat: 사다리 높이 예외 처리 테스트 구현
yeeun0702 May 5, 2024
c393e56
feat: 사다리 높이 예외 처리 구현
yeeun0702 May 5, 2024
065ab77
feat: Person, LadderMaker 예외처리 적용
yeeun0702 May 5, 2024
d48d812
test: PersonList 테스트 구현
sojeong0202 May 5, 2024
2b1b138
feat: PersonList 구현
sojeong0202 May 5, 2024
b5a1dde
test: 사다리 가로라인에서 True가 겹치면 재조정하는 메소드 테스트코드 구현
yeeun0702 May 6, 2024
9ec9c84
feat: Line 구현
yeeun0702 May 6, 2024
f064504
feat: Line 구현
yeeun0702 May 6, 2024
df1619c
test: 입력 받은 이름 재가공 메소드 테스트 구현
sojeong0202 May 8, 2024
6b7e70d
feat: 입력 받은 이름 재가공 하는 메소드 구현
sojeong0202 May 8, 2024
e48df59
feat: 정해진 조건대로 사람 이름출력
yeeun0702 May 8, 2024
5a2720c
feat: Controller 1차 구현
yeeun0702 May 8, 2024
5326a52
feat: 매개변수로 입력받은 불리언 리스트에 따라 사다리 출력 메소드 구현
sojeong0202 May 8, 2024
4b112ad
feat: controller 구현 완료
sojeong0202 May 8, 2024
314556b
style: 코드 포맷 변경
yeeun0702 May 8, 2024
2f6fbc8
refactor: PersonList를 분리하여 manipulationPeople과 PersonList를 일급 컬렉션으로 만듬
yeeun0702 May 11, 2024
59d40d4
refactor: 일급 컬렉션 적용 수정
yeeun0702 May 11, 2024
5ad3bcb
refactor: Line 클래스 분리
sojeong0202 May 11, 2024
d638722
style: 코드 컨벤션 적용
sojeong0202 May 11, 2024
7ee1e78
Changes by LG
sojeong0202 May 21, 2024
8aca3fc
Revert "Changes by LG"
sojeong0202 May 21, 2024
51e9a38
docs: 리뷰 후 개선 방향 작성
sojeong0202 May 21, 2024
bc07ed7
refactor: 사다리 문자 함수에서 상수로 변경
sojeong0202 May 21, 2024
b94dad2
refactor: 예외 상황을 예외 클래스들로 분리
sojeong0202 May 21, 2024
758df14
refactor: InputView 클래스의 inputName() 메소드 명을 복수형으로 변경
sojeong0202 May 21, 2024
1d149e7
refactor: hasDuplicatePersonName() 메소드 내부 스트림으로 변경
sojeong0202 May 21, 2024
9781bb0
refactor: 랜덤 클래스를 LadderMaker 클래스의 메소드로 변경
sojeong0202 May 21, 2024
e5e4cde
refactor: LineTest에서 points 리스트 변경
sojeong0202 May 21, 2024
7c38527
refactor: PersonListTest에 랜덤한 값에 대해서 테스트로 변경
sojeong0202 May 21, 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
65 changes: 65 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## 리뷰 후 개선 방향
- [x] 사디리 문자 함수를 상수로 따로 뺴기
- [x] enum을 클래스 변수로 잡고 각 예외 상황에 대한 예외 클래스들로 변경히기
- [x] List.of로 변경하기
- [x] 함수명을 복수형으로 변경하기
- [x] hasDuplicatePersonName() 메소드 내부 stream으로 변경
- [x] 랜덤 클래스를 메소드로 변경(사용하는 클래스 안으로)
- [x] PersonListTest, 랜덤한 값에 대해서 테스트 작성

---
## 기능 구현 목록

### 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을 적용한다.
- 모든 원시 값과 문자열을 포장한다
- 줄여 쓰지 않는다(축약 금지).
- 일급 컬렉션을 쓴다.
-
13 changes: 13 additions & 0 deletions src/main/java/ladder/Application.java
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();
}
}
45 changes: 45 additions & 0 deletions src/main/java/ladder/controller/LadderController.java
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.inputNames()).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);
}
}
42 changes: 42 additions & 0 deletions src/main/java/ladder/model/LadderMaker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ladder.model;

import static ladder.util.validator.LadderValidator.checkEmpty;
import static ladder.util.validator.LadderValidator.checkLadderNumberStandard;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class LadderMaker {

private final int ladderHeight;

public LadderMaker(String ladderHeight) {
checkEmpty(ladderHeight);
checkLadderNumberStandard(ladderHeight);

this.ladderHeight = Integer.parseInt(ladderHeight);
}

public int getLadderHeight() {
return ladderHeight;
}

public List<Boolean> makeLadder(int personCount) {
Line lines = new Line(createRandomColumn(personCount));
return lines.getPoints();
}

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();
}
}
28 changes: 28 additions & 0 deletions src/main/java/ladder/model/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ladder.model;

import java.util.List;

public class Line {

private final 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;
}
}
}
44 changes: 44 additions & 0 deletions src/main/java/ladder/model/ManipulationPeople.java
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();
}
}
21 changes: 21 additions & 0 deletions src/main/java/ladder/model/Person.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ladder.model;

import static ladder.util.validator.PersonValidator.checkEmpty;
import static ladder.util.validator.PersonValidator.checkOverRange;
import static ladder.util.validator.PersonValidator.checkSpace;

public class Person {

private final String name;

public Person(String name) {
checkEmpty(name);
checkOverRange(name);
checkSpace(name);
this.name = name;
}

public String getName() {
return name;
}
}
28 changes: 28 additions & 0 deletions src/main/java/ladder/model/PersonList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ladder.model;

import static ladder.util.validator.PersonValidator.checkDuplicate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class PersonList {

private final List<Person> people = new ArrayList<>();

public PersonList(String nameList) {
checkDuplicate(nameList);
personNameInput(nameList);
}

public List<Person> getPeople() {
return Collections.unmodifiableList(people);
}

private void personNameInput(String nameList) {
for (String personName : nameList.split(",")) {
people.add(new Person(personName));
}
}
}
15 changes: 15 additions & 0 deletions src/main/java/ladder/util/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ladder.util;

public enum ErrorMessage {
Copy link
Collaborator

Choose a reason for hiding this comment

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

error 메세지를 enum으로 나눈 것에 칭찬드려요!

하지만 이 프로젝트에서 거의 모든 예외가 RuntimeException(IllegalArgumentException)으로 처리되서 개발자가 봤을 때 명확한 오류를 찾기위해서는 message를 봐야한다는 점이 아쉬운 것 같아요.

enum을 클래스 변수로 잡고 각 예외 상황에 대한 예외클래스들로 변경하여 리팩토링 하면 로직, 테스트 면에서도 더 명확해질 것 같아요.


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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public abstract class CustomAbstractException extends RuntimeException {

private final ErrorMessage errorMessage;

protected CustomAbstractException(ErrorMessage errorMessage) {
this.errorMessage = errorMessage;
}

public String getErrorMessage() {
return errorMessage.message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public class InputStringBlankException extends CustomAbstractException {
public InputStringBlankException() {
super(ErrorMessage.INPUT_STRING_BLANK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public class InputStringNullException extends CustomAbstractException {
public InputStringNullException() {
super(ErrorMessage.INPUT_STRING_NOT_NULL);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public class LadderNumberIllegalException extends CustomAbstractException {
public LadderNumberIllegalException() {
super(ErrorMessage.INPUT_LADDER_NUMBER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public class NameDuplicateException extends CustomAbstractException {
public NameDuplicateException() {
super(ErrorMessage.INPUT_STRING_DUPLICATE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ladder.util.validator.Exception;

import ladder.util.ErrorMessage;

public class PersonNameIllegalException extends CustomAbstractException {
public PersonNameIllegalException() {
super(ErrorMessage.INPUT_PERSON_NAME_IS_INCORRECT);
}
}
Loading