Skip to content
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

Open
wants to merge 29 commits into
base: main
Choose a base branch
from

Conversation

yeeun0702
Copy link

😱 어려웠던 점

일급 컬렉션을 적용하는 것이 너무 어려웠어요. 그리고 각 기능마다 TDD를 작성한 다음, 코드를 짜는게 낯설게 느껴졌습니다. MVC 패턴을 적용할 때, View가 특정 모델에 의존하지 않게 짜도록 고민하는 것도 어려웠습니다.

🧐 궁금한 점

일급 컬렉션을 잘 사용했을까요 ? 그리고 클래스를 추가로 분리하거나 합쳐야 될 것이 있을지 궁금합니다. 또한 추가로 테스트코드를 작성해야하는 부분이 있다면 알려주세요 ! 어떤 테스트 메소드들을 많이 사용하는지 궁금합니다.

✍️ 느낀 점

TDD를 기능단위로 구현하고 코드를 짜는 게 쉽지 않았습니다. 또한 MVC 패턴을 적용하는 것에 대해 더 깊이 고민할 수 있었습니다. 지난 미션보다 기간이 늘어나면서 페어와 더 많은 시간을 들여 코드를 작성하다보니, 더 완성도 있게 제출할 수 있어서 좋았습니다.

yeeun0702 and others added 25 commits May 5, 2024 12:52
- 사람 이름 공백 예외 처리
- 사람 이름 null 예외 처리
- 사람 이름 겹칠 때 예외 처리
-사람 이름 공백 예외 처리
-사람 이름 null 예외 처리
-사람 이름 겹칠 때 예외 처리
- 쉼표 기준으로 이름 분리해서 Person 인스턴스 생성 후
- PersonList에 Person 인스턴스 넣는 기능 테스트
- 쉼표 기준으로 이름 분리해서 Person 인스턴스 생성 후 PersonList에 Person 인스턴스 넣는 기능 구현
- 한 줄 랜덤 생성 로직과 재가공하는 로직 분리
Copy link

@hangillee hangillee left a comment

Choose a reason for hiding this comment

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

안녕하세요, 예은! 👋
중간고사 이후에 놀고 싶었을 텐데 미션하느라 고생 많으셨어요~

TDD와 일급 컬렉션 활용이 어려웠군요.. 저도 처음엔 정말 많이 어려웠습니다.
일급 컬렉션은 평소에 사용하는 자료구조도 아닐 뿐더러 생소한 개념이라 이해하기 힘든게 당연합니다.

TDD도 마찬가지로 누가 강요하지도 않을 뿐더러, 오히려 유지보수하기 힘들어질 수도 있습니다.
리뷰 코멘트에도 달아뒀지만 테스트 커버리지를 참고해서 테스트되지 않은 메소드들의 테스트를
작성해주세요! 남은 기간도 파이팅입니다!

docs/README.md Outdated
- [x] 이름이 5글자일 경우, 이름의 끝 글자를 기준으로 입력 받은 높이만큼 사다리의 세로 라인 출력
- [x] 이름이 5글자 이하인 경우, 이름의 끝 글자 + 공백문자를 기준으로 입력 받은 높이만큼 사다리의 세로 라인 출력
- [x] 사다리가 정상적으로 작동하려면 가로 라인이 겹치지 않게 하기(ex.`|-----|-----|`)
- x] 사다리 라인(`|-----|`)

Choose a reason for hiding this comment

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

사소하지만 오타는 가독성을 해치곤 합니다. 다음부턴 신경써주세요! 😁

docs/README.md Outdated
Comment on lines 1 to 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을 적용한다.
- 모든 원시 값과 문자열을 포장한다
- 줄여 쓰지 않는다(축약 금지).
- 일급 컬렉션을 쓴다.
-

Choose a reason for hiding this comment

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

요구 사항 정리 👍

Comment on lines +6 to +26
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();
}
}

Choose a reason for hiding this comment

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

이 클래스의 이름이 LadderMaker였어야 할까요? List<Line>을 가진 LadderLines였다면 어땠을까요?
사람 수만큼 여러 라인들을 생성하고 조립하여 하나의 사다리를 만드는 일급 컬렉션으로 볼 수 있지 않을까요?

Comment on lines 20 to 30
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;
}
}
}

Choose a reason for hiding this comment

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

컨벤션 상, rearRange가 더 어울리는 이름이 아닐까요?

Comment on lines 20 to 30
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;
}
}
}

Choose a reason for hiding this comment

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

요구 사항에도 적혀있지만 이번 미션에서는 indent(들여쓰기)를 1로 제한하고 있습니다.
해당 메소드는 indent가 2까지 내려가있습니다. 리팩토링 해볼까요?

힌트를 드리자면, 메소드 분리 혹은 로직 자체의 리팩토링이 방법이 될 수 있습니다.
구현이 어렵더라도 습관적으로 indent를 줄이려고 노력해야 합니다. (indent는 가독성에 큰 영향을 미칩니다.)

Comment on lines +37 to +45
for (boolean elementLine : lines) {
if (elementLine) {
lineBuilder.append(containPrintHorizontalLine());
}

if (!elementLine) {
lineBuilder.append(onlyVerticalLine());
}
}

Choose a reason for hiding this comment

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

마찬가지로 indent를 줄여봅시다.

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class LadderTest {

Choose a reason for hiding this comment

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

Test 팁이자 IntelliJ 팁입니다.

스크린샷 2024-05-17 오후 5 45 44

테스트 커버리지를 확인해보면 테스트에서 한 번도 호출되지 않은 메소드나 클래스를 확인할 수 있습니다.
View(입출력)에 대한 테스트는 굳이 필요하지 않고, 도메인 로직에 대한 테스트는 필수입니다.

Comment on lines 15 to 22
@Test
@DisplayName("사다리 null일 때 예외 처리 테스트")
void should_ThrowException_When_IsLadderNumberNull() {
RuntimeException exception = Assertions.assertThrows(RuntimeException.class, () -> {
LadderValidator.checkEmpty(null);
});
Assertions.assertEquals(INPUT_STRING_NOT_NULL.message, exception.getMessage());
}

Choose a reason for hiding this comment

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

AssertJassertThatThrownBy()라는 메소드가 있습니다.

어떤 코드를 실행 했을 때, 특정 예외가 발생하는지 검증하는 테스트 메소드입니다. 활용해봅시다!

Comment on lines +24 to +25
@ParameterizedTest
@ValueSource(strings = {"0", "-1", "1.1", "abc", ""})

Choose a reason for hiding this comment

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

@ParameterizedTeset 👍

class LineTest {
@Test
@DisplayName("사다리 가로라인(Line)을 겹치지 않게 생성하는 메소드 테스트")
void should_ReraangeLadderLine_When_DuplicateTrue() {

Choose a reason for hiding this comment

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

테스트 메소드의 이름을 스네이크 케이스로 작성한 이유가 있나요?

Copy link
Author

Choose a reason for hiding this comment

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

테스트 메서드 명은 주로 문장으로 작성되어서 길어지기 때문에
가독성을 위해서 camel case보다 snake case를 선택해서 작성했습니다 !

위 질문을 통해
https://blog.naver.com/PostView.naver?blogId=ki630808&logNo=222175522625
https://daryeou.tistory.com/17 등의 내용을 보면서 네이밍 규칙에 대해서 더 학습해보았습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants