From a0d5531f2fdb4c3f8547e953bd4adb46c38acdbf Mon Sep 17 00:00:00 2001 From: minji-go Date: Wed, 2 Apr 2025 01:31:27 +0900 Subject: [PATCH 01/15] =?UTF-8?q?refactor:=20@FunctionalInterface=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- src/main/java/nextstep/fp/Lambda.java | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc0f757d0b..7ce5e7488b 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ > - 익명 클래스를 람다로 전환 : nextstep.fp.CarTest 이동, 정지 method - [x] 람다 실습 2 > - 람다를 활용해 중복 제거 : nextstep.fp.Lambda의 sumAll, sumAllEven, sumAllOverThree method -- [x] 흰트 +- [x] 힌트 > - 변경되는 부분과 변경되지 않는 부분의 코드를 분리한다. > - 변경되는 부분을 인터페이스로 추출한다. > - 인터페이스에 대한 구현체를 익명 클래스(anonymous class)로 구현해 메소드의 인자로 전달한다. @@ -76,3 +76,6 @@ > - Arrays.stream()을 이용해 배열을 stream으로 생성할 수 있다. > - 일치하는 값 하나를 추출할 때 findFirst() 메소드를 활용 가능하다. > - Optional의 orElseThrow() 메소드 활용해 구현한다. + +### 코멘트 +- [x] 함수형 인터페이스는 애너테이션 `@FunctionalInterface`으로 선언 \ No newline at end of file diff --git a/src/main/java/nextstep/fp/Lambda.java b/src/main/java/nextstep/fp/Lambda.java index 094ca80bbd..553cc38d41 100644 --- a/src/main/java/nextstep/fp/Lambda.java +++ b/src/main/java/nextstep/fp/Lambda.java @@ -45,6 +45,7 @@ private static int sumBy(List numbers, SumCondition condition) { .orElse(0); } + @FunctionalInterface public interface SumCondition { boolean match(int number); } From 0d49e96bbe2f97d20eee5cc5ec3081bedf95ad94 Mon Sep 17 00:00:00 2001 From: minji-go Date: Wed, 2 Apr 2025 01:31:52 +0900 Subject: [PATCH 02/15] =?UTF-8?q?docs:=20step2=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ce5e7488b..8f01b6a692 100644 --- a/README.md +++ b/README.md @@ -78,4 +78,60 @@ > - Optional의 orElseThrow() 메소드 활용해 구현한다. ### 코멘트 -- [x] 함수형 인터페이스는 애너테이션 `@FunctionalInterface`으로 선언 \ No newline at end of file +- [x] 함수형 인터페이스는 애너테이션 `@FunctionalInterface`으로 선언 + +--- +## STEP2. 사다리(생성) +### 기능 요구사항 +> - 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. +> - 사람 이름은 쉼표(,)를 기준으로 구분한다. +> - 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. +> - 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. + > - |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. + +- [ ] 사다리 게임에 참여하는 사람의 이름은 최대 5글자이다. +- [ ] 사다리 게임에 참여하는 사람의 이름은 쉼표(,)를 기준으로 구분한다. +- [ ] 사다리 게임은 참여하는 사람의 이름과 최대 사다리 높이를 전달받는다. +- [ ] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. +- [ ] 사다리 타기는 라인이 겹치지 않는다. +- [ ] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. +- [ ] 사다리는 랜덤값 등 사다리 생성 전략 따라서 생성한다. + +### 프로그래밍 요구사항 +> - 자바 8의 스트림과 람다를 적용해 프로그래밍한다. +> - 규칙 6: 모든 엔티티를 작게 유지한다. + +실행 결과 +``` +참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요) +pobi,honux,crong,jk + +최대 사다리 높이는 몇 개인가요? +5 + +실행결과 + +pobi honux crong jk + |-----| |-----| + | |-----| | + |-----| | | + | |-----| | + |-----| |-----| +``` + +### 힌트 +> - 2차원 배열을 ArrayList, Generic을 적용해 구현하면 ArrayList>와 같이 이해하기 어려운 코드가 추가된다. +> - 사다리 게임에서 한 라인의 좌표 값을 가지는 객체를 추가해 구현해 본다. +> - 아래와 같이 Line 객체를 추가하면 ArrayList> 코드를 ArrayList과 같이 구현하는 것이 가능해 진다. + +```java +public class Line { + private List points = new ArrayList<>(); + + public Line (int countOfPerson) { + // 라인의 좌표 값에 선이 있는지 유무를 판단하는 로직 추가 + } + + [...] +} +``` From 1107b1938a52d0e63d5883db1fce4e7ee56f99c2 Mon Sep 17 00:00:00 2001 From: minji-go Date: Thu, 3 Apr 2025 19:49:52 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++-- .../java/ladder/domain/LadderFactory.java | 28 +++++++++++++++++++ .../java/ladder/domain/LadderFactoryTest.java | 25 +++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ladder/domain/LadderFactory.java create mode 100644 src/test/java/ladder/domain/LadderFactoryTest.java diff --git a/README.md b/README.md index 8f01b6a692..94823b6306 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,9 @@ > - 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. > - |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. -- [ ] 사다리 게임에 참여하는 사람의 이름은 최대 5글자이다. -- [ ] 사다리 게임에 참여하는 사람의 이름은 쉼표(,)를 기준으로 구분한다. -- [ ] 사다리 게임은 참여하는 사람의 이름과 최대 사다리 높이를 전달받는다. +- [x] 사다리 게임에 참여하는 사람의 이름은 최대 5글자이다. +- [x] 사다리 게임에 참여하는 사람의 이름은 쉼표(,)를 기준으로 구분한다. +- [x] 사다리 게임은 참여하는 사람의 이름과 최대 사다리 높이를 전달받는다. - [ ] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. - [ ] 사다리 타기는 라인이 겹치지 않는다. - [ ] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java new file mode 100644 index 0000000000..d0f42f8f64 --- /dev/null +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -0,0 +1,28 @@ +package ladder.domain; + +import java.util.Arrays; +import java.util.List; + +public class LadderFactory { + private List names; + private int height; + + public LadderFactory(String namesText, int height) { + List names = Arrays.asList(namesText.split(",")); + validateNameMaxLength(names); + validLadderHeight(height); + this.names = names; + this.height = height; + } + + private void validLadderHeight(int height) { + if(height <= 0) + throw new IllegalArgumentException("The ladder height should be larger than zero."); + } + + private void validateNameMaxLength(List names) { + if (names.stream().anyMatch(name -> name.length() > 5)) + throw new IllegalArgumentException("The name should be up to 5 letters."); + + } +} diff --git a/src/test/java/ladder/domain/LadderFactoryTest.java b/src/test/java/ladder/domain/LadderFactoryTest.java new file mode 100644 index 0000000000..19ae6c9a5f --- /dev/null +++ b/src/test/java/ladder/domain/LadderFactoryTest.java @@ -0,0 +1,25 @@ +package ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class LadderFactoryTest { + + @Test + @DisplayName("사다리 게임에 참여하는 사람의 이름은 최대 5글자이다.") + void validateNameLengthShouldBeLessThan5() { + assertThatThrownBy(() -> new LadderFactory("sunny,universe", 2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("사다리 게임에 입력하는 사다리 높이는 양수여야 한다.") + void validateLadderHeightShouldBeLargerThan0() { + assertThatThrownBy(() -> new LadderFactory("sunny,univ", -1)) + .isInstanceOf(IllegalArgumentException.class); + } + +} \ No newline at end of file From ec8d0fccbec8d90b70f03d1dbb3fff2427b80f73 Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 00:10:41 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../java/ladder/domain/LadderFactory.java | 12 +++++++++++ src/main/java/ladder/view/InputView.java | 21 +++++++++++++++++++ .../java/ladder/domain/LadderFactoryTest.java | 11 +++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ladder/view/InputView.java diff --git a/README.md b/README.md index 94823b6306..81bae16cc4 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ - [x] 사다리 게임에 참여하는 사람의 이름은 최대 5글자이다. - [x] 사다리 게임에 참여하는 사람의 이름은 쉼표(,)를 기준으로 구분한다. - [x] 사다리 게임은 참여하는 사람의 이름과 최대 사다리 높이를 전달받는다. -- [ ] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. +- [x] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. - [ ] 사다리 타기는 라인이 겹치지 않는다. - [ ] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. - [ ] 사다리는 랜덤값 등 사다리 생성 전략 따라서 생성한다. diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index d0f42f8f64..b72bbd38f8 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -1,5 +1,6 @@ package ladder.domain; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -25,4 +26,15 @@ private void validateNameMaxLength(List names) { throw new IllegalArgumentException("The name should be up to 5 letters."); } + + public List> getLadder() { + List> result = new ArrayList<>(); + for (int i=0; i()); + for(int j=0; j width.size() == 2); + } +} + From a1678ef85400167768224eff9dccb00f6819a57f Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 00:28:57 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EA=B2=B9=EC=B9=A8=20=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- .../java/ladder/domain/LadderFactory.java | 23 +++++++++++++++---- .../java/ladder/domain/LineGenerator.java | 5 ++++ .../ladder/domain/RandomLineGenerator.java | 12 ++++++++++ .../java/ladder/domain/LadderFactoryTest.java | 12 +++++++++- 5 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ladder/domain/LineGenerator.java create mode 100644 src/main/java/ladder/domain/RandomLineGenerator.java diff --git a/README.md b/README.md index 81bae16cc4..275014949a 100644 --- a/README.md +++ b/README.md @@ -93,9 +93,9 @@ - [x] 사다리 게임에 참여하는 사람의 이름은 쉼표(,)를 기준으로 구분한다. - [x] 사다리 게임은 참여하는 사람의 이름과 최대 사다리 높이를 전달받는다. - [x] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. -- [ ] 사다리 타기는 라인이 겹치지 않는다. +- [x] 사다리 타기는 라인이 겹치지 않는다. +- [x] 사다리는 랜덤값 등 사다리 생성 전략 따라서 생성한다. - [ ] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. -- [ ] 사다리는 랜덤값 등 사다리 생성 전략 따라서 생성한다. ### 프로그래밍 요구사항 > - 자바 8의 스트림과 람다를 적용해 프로그래밍한다. diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index b72bbd38f8..82fedfd591 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Random; public class LadderFactory { private List names; @@ -27,14 +28,26 @@ private void validateNameMaxLength(List names) { } - public List> getLadder() { + public List> getLadder(LineGenerator generator) { List> result = new ArrayList<>(); for (int i=0; i()); - for(int j=0; j createLines(LineGenerator generator) { + List lines = new ArrayList<>(); + + for(int i=0; i0 && lines.get(i-1) != null && lines.get(i-1)) { + lines.add(false); + continue; + } + boolean connected = generator.isConnected(); + lines.add(connected); + + } + return lines; + } } diff --git a/src/main/java/ladder/domain/LineGenerator.java b/src/main/java/ladder/domain/LineGenerator.java new file mode 100644 index 0000000000..1cec241fc6 --- /dev/null +++ b/src/main/java/ladder/domain/LineGenerator.java @@ -0,0 +1,5 @@ +package ladder.domain; + +public interface LineGenerator { + boolean isConnected(); +} diff --git a/src/main/java/ladder/domain/RandomLineGenerator.java b/src/main/java/ladder/domain/RandomLineGenerator.java new file mode 100644 index 0000000000..3f66e4644e --- /dev/null +++ b/src/main/java/ladder/domain/RandomLineGenerator.java @@ -0,0 +1,12 @@ +package ladder.domain; + +import java.util.Random; + +public class RandomLineGenerator implements LineGenerator { + public static final Random random = new Random(); + + @Override + public boolean isConnected() { + return random.nextBoolean(); + } +} diff --git a/src/test/java/ladder/domain/LadderFactoryTest.java b/src/test/java/ladder/domain/LadderFactoryTest.java index 8715421c02..534a28a7fd 100644 --- a/src/test/java/ladder/domain/LadderFactoryTest.java +++ b/src/test/java/ladder/domain/LadderFactoryTest.java @@ -1,8 +1,11 @@ package ladder.domain; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.*; @@ -26,9 +29,16 @@ void validateLadderHeightShouldBeLargerThan0() { @Test @DisplayName("사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다.") void getLadder() { - assertThat(new LadderFactory("red,blue,green",3).getLadder()) + assertThat(new LadderFactory("red,blue,green",3).getLadder(() -> true)) .hasSize(3) .allMatch(width -> width.size() == 2); } + + @Test + @DisplayName("사다리 타기는 라인이 겹치지 않는다.") + void lineShouldNotOverlap() { + assertThat(new LadderFactory("red,blue,green",3).getLadder(() -> true)) + .allMatch(width -> !width.equals(List.of(true, true))); + } } From 58927b449885c7a7867f550cd991c0bbe4da93fa Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 00:33:54 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EC=B0=B8=EC=97=AC=EC=9E=90=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/ladder/domain/LadderFactory.java | 9 +++++---- src/test/java/ladder/domain/LadderFactoryTest.java | 6 ++++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 275014949a..f1b65e4eea 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ - [x] 사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다. - [x] 사다리 타기는 라인이 겹치지 않는다. - [x] 사다리는 랜덤값 등 사다리 생성 전략 따라서 생성한다. -- [ ] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. +- [x] 사다리의 폭은 최대 글자 수 만큼으로 출력한다. ### 프로그래밍 요구사항 > - 자바 8의 스트림과 람다를 적용해 프로그래밍한다. diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index 82fedfd591..e8387a6f10 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -1,9 +1,6 @@ package ladder.domain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; +import java.util.*; public class LadderFactory { private List names; @@ -50,4 +47,8 @@ private List createLines(LineGenerator generator) { } return lines; } + + public List getNames() { + return Collections.unmodifiableList(names); + } } diff --git a/src/test/java/ladder/domain/LadderFactoryTest.java b/src/test/java/ladder/domain/LadderFactoryTest.java index 534a28a7fd..5b08eaeb9a 100644 --- a/src/test/java/ladder/domain/LadderFactoryTest.java +++ b/src/test/java/ladder/domain/LadderFactoryTest.java @@ -40,5 +40,11 @@ void lineShouldNotOverlap() { assertThat(new LadderFactory("red,blue,green",3).getLadder(() -> true)) .allMatch(width -> !width.equals(List.of(true, true))); } + + @Test + @DisplayName("사다리 타기 참여자의 이름을 얻는다.") + void getNames() { + assertThat(new LadderFactory("red,blue,green", 1).getNames()).contains("red", "blue", "green"); + } } From f56bb41fb50ab7d505b88f3ecb98396fbbd21ffd Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 00:42:36 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/LadderApplication.java | 19 ++++++++++++++ src/main/java/ladder/view/OutputView.java | 29 +++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/main/java/ladder/LadderApplication.java create mode 100644 src/main/java/ladder/view/OutputView.java diff --git a/src/main/java/ladder/LadderApplication.java b/src/main/java/ladder/LadderApplication.java new file mode 100644 index 0000000000..4ffb4db1c2 --- /dev/null +++ b/src/main/java/ladder/LadderApplication.java @@ -0,0 +1,19 @@ +package ladder; + +import ladder.domain.LadderFactory; +import ladder.domain.RandomLineGenerator; +import ladder.view.InputView; +import ladder.view.OutputView; + + +public class LadderApplication { + + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + + LadderFactory ladderFactory = new LadderFactory(inputView.inputNames(), inputView.inputHeight()); + outputView.printNames(ladderFactory.getNames()); + outputView.printLadders(ladderFactory.getLadder(new RandomLineGenerator())); + } +} diff --git a/src/main/java/ladder/view/OutputView.java b/src/main/java/ladder/view/OutputView.java new file mode 100644 index 0000000000..d2ca74cd7a --- /dev/null +++ b/src/main/java/ladder/view/OutputView.java @@ -0,0 +1,29 @@ +package ladder.view; + +import java.util.List; + +public class OutputView { + public void printNames(List names) { + System.out.println("실행결과"); + System.out.println(); + + for(String name : names) { + System.out.print(String.format("%5s ", name)); + } + System.out.println(); + } + + public void printLadders(List> ladders) { + for(List ladder : ladders) { + System.out.print(" "); + for(Boolean connected : ladder) { + if(connected) { + System.out.print("|-----"); + } else { + System.out.print("| "); + } + } + System.out.println("|"); + } + } +} From bc583e0845eab468c3e9b98c139fd52f66c3f1d3 Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 01:22:35 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20Ladders=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/LadderApplication.java | 2 +- .../java/ladder/domain/LadderFactory.java | 46 ++++++------------- src/main/java/ladder/domain/Ladders.java | 45 ++++++++++++++++++ .../java/ladder/domain/LadderFactoryTest.java | 6 +-- 4 files changed, 63 insertions(+), 36 deletions(-) create mode 100644 src/main/java/ladder/domain/Ladders.java diff --git a/src/main/java/ladder/LadderApplication.java b/src/main/java/ladder/LadderApplication.java index 4ffb4db1c2..6d9d27b571 100644 --- a/src/main/java/ladder/LadderApplication.java +++ b/src/main/java/ladder/LadderApplication.java @@ -14,6 +14,6 @@ public static void main(String[] args) { LadderFactory ladderFactory = new LadderFactory(inputView.inputNames(), inputView.inputHeight()); outputView.printNames(ladderFactory.getNames()); - outputView.printLadders(ladderFactory.getLadder(new RandomLineGenerator())); + outputView.printLadders(ladderFactory.getLadder()); } } diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index e8387a6f10..0cce3c7270 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -1,52 +1,36 @@ package ladder.domain; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class LadderFactory { - private List names; - private int height; + private final List names; + private final Ladders ladders; public LadderFactory(String namesText, int height) { + this(namesText, height, new RandomLineGenerator()); + } + + public LadderFactory(String namesText, int height, LineGenerator lineGenerator) { List names = Arrays.asList(namesText.split(",")); validateNameMaxLength(names); - validLadderHeight(height); this.names = names; - this.height = height; - } - - private void validLadderHeight(int height) { - if(height <= 0) - throw new IllegalArgumentException("The ladder height should be larger than zero."); + this.ladders = new Ladders(height, names.size()-1, lineGenerator); } private void validateNameMaxLength(List names) { if (names.stream().anyMatch(name -> name.length() > 5)) throw new IllegalArgumentException("The name should be up to 5 letters."); - } - public List> getLadder(LineGenerator generator) { - List> result = new ArrayList<>(); - for (int i=0; i> getLadder() { + return ladders.get(); } - private List createLines(LineGenerator generator) { - List lines = new ArrayList<>(); - - for(int i=0; i0 && lines.get(i-1) != null && lines.get(i-1)) { - lines.add(false); - continue; - } - boolean connected = generator.isConnected(); - lines.add(connected); - - } - return lines; - } public List getNames() { return Collections.unmodifiableList(names); diff --git a/src/main/java/ladder/domain/Ladders.java b/src/main/java/ladder/domain/Ladders.java new file mode 100644 index 0000000000..229e435006 --- /dev/null +++ b/src/main/java/ladder/domain/Ladders.java @@ -0,0 +1,45 @@ +package ladder.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Ladders { + private final List> ladders; + + public Ladders(int height, int width, LineGenerator generator) { + validLadderHeight(height); + this.ladders = createLadders(height, width, generator); + } + + private void validLadderHeight(int height) { + if (height <= 0) + throw new IllegalArgumentException("The ladder height should be larger than zero."); + } + + private List> createLadders(int height, int width, LineGenerator generator) { + return IntStream.range(0, height) + .mapToObj(i -> createLines(width, generator)) + .collect(Collectors.toList()); + } + + private List createLines(int width, LineGenerator generator) { + List lines = new ArrayList<>(); + + for (int i = 0; i < width - 1; i++) { + boolean connected = generator.isConnected(); + lines.add(connected); + if (connected && i < width) { + lines.add(false); + i++; + } + } + return lines; + } + + public List> get() { + return Collections.unmodifiableList(ladders); + } +} diff --git a/src/test/java/ladder/domain/LadderFactoryTest.java b/src/test/java/ladder/domain/LadderFactoryTest.java index 5b08eaeb9a..a9ddafefff 100644 --- a/src/test/java/ladder/domain/LadderFactoryTest.java +++ b/src/test/java/ladder/domain/LadderFactoryTest.java @@ -1,14 +1,12 @@ package ladder.domain; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; class LadderFactoryTest { @@ -29,7 +27,7 @@ void validateLadderHeightShouldBeLargerThan0() { @Test @DisplayName("사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다.") void getLadder() { - assertThat(new LadderFactory("red,blue,green",3).getLadder(() -> true)) + assertThat(new LadderFactory("red,blue,green",3, () -> true).getLadder()) .hasSize(3) .allMatch(width -> width.size() == 2); } @@ -37,7 +35,7 @@ void getLadder() { @Test @DisplayName("사다리 타기는 라인이 겹치지 않는다.") void lineShouldNotOverlap() { - assertThat(new LadderFactory("red,blue,green",3).getLadder(() -> true)) + assertThat(new LadderFactory("red,blue,green",3, () -> true).getLadder()) .allMatch(width -> !width.equals(List.of(true, true))); } From f8a22621bdc924d722404bbc79f53408d71ef89e Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 01:28:38 +0900 Subject: [PATCH 09/15] =?UTF-8?q?feat:=20Names=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ladder/domain/LadderFactory.java | 23 ++++------------ src/main/java/ladder/domain/Ladders.java | 2 +- src/main/java/ladder/domain/Names.java | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 src/main/java/ladder/domain/Names.java diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index 0cce3c7270..9647c40f98 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -1,14 +1,9 @@ package ladder.domain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public class LadderFactory { - private final List names; + private final Names names; private final Ladders ladders; public LadderFactory(String namesText, int height) { @@ -16,23 +11,15 @@ public LadderFactory(String namesText, int height) { } public LadderFactory(String namesText, int height, LineGenerator lineGenerator) { - List names = Arrays.asList(namesText.split(",")); - validateNameMaxLength(names); - this.names = names; - this.ladders = new Ladders(height, names.size()-1, lineGenerator); - } - - private void validateNameMaxLength(List names) { - if (names.stream().anyMatch(name -> name.length() > 5)) - throw new IllegalArgumentException("The name should be up to 5 letters."); + this.names = new Names(namesText); + this.ladders = new Ladders(height, names.connectSize(), lineGenerator); } public List> getLadder() { - return ladders.get(); + return ladders.getAll(); } - public List getNames() { - return Collections.unmodifiableList(names); + return names.getAll(); } } diff --git a/src/main/java/ladder/domain/Ladders.java b/src/main/java/ladder/domain/Ladders.java index 229e435006..dfff2d31dd 100644 --- a/src/main/java/ladder/domain/Ladders.java +++ b/src/main/java/ladder/domain/Ladders.java @@ -39,7 +39,7 @@ private List createLines(int width, LineGenerator generator) { return lines; } - public List> get() { + public List> getAll() { return Collections.unmodifiableList(ladders); } } diff --git a/src/main/java/ladder/domain/Names.java b/src/main/java/ladder/domain/Names.java new file mode 100644 index 0000000000..ed9d7c3c33 --- /dev/null +++ b/src/main/java/ladder/domain/Names.java @@ -0,0 +1,27 @@ +package ladder.domain; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class Names { + private final List names; + + public Names(String text) { + this.names = Arrays.asList(text.split(",")); + validateNameMaxLength(names); + } + + private void validateNameMaxLength(List names) { + if (names.stream().anyMatch(name -> name.length() > 5)) + throw new IllegalArgumentException("The name should be up to 5 letters."); + } + + public List getAll() { + return Collections.unmodifiableList(names); + } + + public int connectSize() { + return names.size() - 1; + } +} From 8b01169b528cb0ca90ed45444b34a4608013ad4d Mon Sep 17 00:00:00 2001 From: minji-go Date: Fri, 4 Apr 2025 19:36:03 +0900 Subject: [PATCH 10/15] =?UTF-8?q?feat:=20Line=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ladder/domain/LadderFactory.java | 7 +-- src/main/java/ladder/domain/Ladders.java | 45 ------------------- src/main/java/ladder/domain/Line.java | 37 +++++++++++++++ src/main/java/ladder/domain/Lines.java | 32 +++++++++++++ src/test/java/ladder/domain/LineTest.java | 25 +++++++++++ ...FactoryTest.java => LinesFactoryTest.java} | 14 ++---- src/test/java/ladder/domain/LinesTest.java | 25 +++++++++++ src/test/java/ladder/domain/NamesTest.java | 30 +++++++++++++ 8 files changed, 157 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/ladder/domain/Ladders.java create mode 100644 src/main/java/ladder/domain/Line.java create mode 100644 src/main/java/ladder/domain/Lines.java create mode 100644 src/test/java/ladder/domain/LineTest.java rename src/test/java/ladder/domain/{LadderFactoryTest.java => LinesFactoryTest.java} (70%) create mode 100644 src/test/java/ladder/domain/LinesTest.java create mode 100644 src/test/java/ladder/domain/NamesTest.java diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index 9647c40f98..f1c6a7c9a4 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -4,7 +4,8 @@ public class LadderFactory { private final Names names; - private final Ladders ladders; + private final Lines lines + ; public LadderFactory(String namesText, int height) { this(namesText, height, new RandomLineGenerator()); @@ -12,11 +13,11 @@ public LadderFactory(String namesText, int height) { public LadderFactory(String namesText, int height, LineGenerator lineGenerator) { this.names = new Names(namesText); - this.ladders = new Ladders(height, names.connectSize(), lineGenerator); + this.lines = new Lines(height, names.connectSize(), lineGenerator); } public List> getLadder() { - return ladders.getAll(); + return lines.getList(); } public List getNames() { diff --git a/src/main/java/ladder/domain/Ladders.java b/src/main/java/ladder/domain/Ladders.java deleted file mode 100644 index dfff2d31dd..0000000000 --- a/src/main/java/ladder/domain/Ladders.java +++ /dev/null @@ -1,45 +0,0 @@ -package ladder.domain; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public class Ladders { - private final List> ladders; - - public Ladders(int height, int width, LineGenerator generator) { - validLadderHeight(height); - this.ladders = createLadders(height, width, generator); - } - - private void validLadderHeight(int height) { - if (height <= 0) - throw new IllegalArgumentException("The ladder height should be larger than zero."); - } - - private List> createLadders(int height, int width, LineGenerator generator) { - return IntStream.range(0, height) - .mapToObj(i -> createLines(width, generator)) - .collect(Collectors.toList()); - } - - private List createLines(int width, LineGenerator generator) { - List lines = new ArrayList<>(); - - for (int i = 0; i < width - 1; i++) { - boolean connected = generator.isConnected(); - lines.add(connected); - if (connected && i < width) { - lines.add(false); - i++; - } - } - return lines; - } - - public List> getAll() { - return Collections.unmodifiableList(ladders); - } -} diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java new file mode 100644 index 0000000000..9e0b16e649 --- /dev/null +++ b/src/main/java/ladder/domain/Line.java @@ -0,0 +1,37 @@ +package ladder.domain; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Line { + private final List line; + + public Line(int width, LineGenerator generator) { + this(createLine(width, generator)); + } + + public Line(List line) { + this.line = line; + } + + private static List createLine(int width, LineGenerator generator) { + List lines = IntStream.range(0, width) + .mapToObj(i -> generator.isConnected()) + .collect(Collectors.toList()); + + for(int i=1; i getList() { + return Collections.unmodifiableList(line); + } + +} diff --git a/src/main/java/ladder/domain/Lines.java b/src/main/java/ladder/domain/Lines.java new file mode 100644 index 0000000000..35966222d3 --- /dev/null +++ b/src/main/java/ladder/domain/Lines.java @@ -0,0 +1,32 @@ +package ladder.domain; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Lines { + private final List lines; + + public Lines(int height, int width, LineGenerator generator) { + validLadderLength(height); + validLadderLength(width); + this.lines = createLadder(height, width, generator); + } + + private void validLadderLength(int value) { + if (value < 1) + throw new IllegalArgumentException("The ladder height should be larger than zero."); + } + + private List createLadder(int height, int width, LineGenerator generator) { + return IntStream.range(0, height) + .mapToObj(i -> new Line(width, generator)) + .collect(Collectors.toList()); + } + + public List> getList() { + return lines.stream() + .map(Line::getList) + .collect(Collectors.toUnmodifiableList()); + } +} diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java new file mode 100644 index 0000000000..ba93545283 --- /dev/null +++ b/src/test/java/ladder/domain/LineTest.java @@ -0,0 +1,25 @@ +package ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class LineTest { + + @Test + @DisplayName("사다리 라인을 생성한다.") + void createLine() { + assertThat(new Line(3, () -> true).getList()).isEqualTo(List.of(true, false, true)); + assertThat(new Line(3, () -> false).getList()).isEqualTo(List.of(false, false, false)); + } + + @Test + @DisplayName("사다리의 라인 하나가 반환된다.") + void getList() { + assertThat(new Line(List.of(true, false, true)).getList()).isEqualTo(List.of(true, false, true)); + } + +} \ No newline at end of file diff --git a/src/test/java/ladder/domain/LadderFactoryTest.java b/src/test/java/ladder/domain/LinesFactoryTest.java similarity index 70% rename from src/test/java/ladder/domain/LadderFactoryTest.java rename to src/test/java/ladder/domain/LinesFactoryTest.java index a9ddafefff..2d1a65840c 100644 --- a/src/test/java/ladder/domain/LadderFactoryTest.java +++ b/src/test/java/ladder/domain/LinesFactoryTest.java @@ -8,14 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -class LadderFactoryTest { +class LinesFactoryTest { - @Test - @DisplayName("사다리 게임에 참여하는 사람의 이름은 최대 5글자이다.") - void validateNameLengthShouldBeLessThan5() { - assertThatThrownBy(() -> new LadderFactory("sunny,universe", 2)) - .isInstanceOf(IllegalArgumentException.class); - } @Test @DisplayName("사다리 게임에 입력하는 사다리 높이는 양수여야 한다.") @@ -27,9 +21,9 @@ void validateLadderHeightShouldBeLargerThan0() { @Test @DisplayName("사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다.") void getLadder() { - assertThat(new LadderFactory("red,blue,green",3, () -> true).getLadder()) - .hasSize(3) - .allMatch(width -> width.size() == 2); + assertThat(new LadderFactory("red,blue",2, () -> true).getLadder()) + .hasSize(2) + .allMatch(width -> width.size() == 1); } @Test diff --git a/src/test/java/ladder/domain/LinesTest.java b/src/test/java/ladder/domain/LinesTest.java new file mode 100644 index 0000000000..b2f5d88fd8 --- /dev/null +++ b/src/test/java/ladder/domain/LinesTest.java @@ -0,0 +1,25 @@ +package ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LinesTest { + + @Test + @DisplayName("사다리 높이는 양수여야 한다.") + void ladderHeightShouldBePositive() { + assertThatThrownBy(() -> new Lines(0, 2, () -> true)).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> new Lines(2, 0, () -> true)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("사다리 높이와 폭은 입력한대로 생성된다.") + void getList() { + assertThat(new Lines(3, 5, () -> true).getList()) + .hasSize(3) + .allMatch(line -> line.size() == 5); + } +} \ No newline at end of file diff --git a/src/test/java/ladder/domain/NamesTest.java b/src/test/java/ladder/domain/NamesTest.java new file mode 100644 index 0000000000..da1a3be0e4 --- /dev/null +++ b/src/test/java/ladder/domain/NamesTest.java @@ -0,0 +1,30 @@ +package ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class NamesTest { + + @Test + @DisplayName("참여자 이름이 최대 글자수를 초과하면 에러가 발생한다.") + void exceedNameLengthLimit() { + assertThatThrownBy(() -> new Names("sunny,universe")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("참여자 이름이 들어간 리스트가 반환된다.") + void getAllNames() { + assertThat(new Names("red,blue,green").getAll()).contains("red", "blue", "green"); + } + + @Test + @DisplayName("참여자 사이의 연결 개수를 반환한다.") + void getConnectSize() { + assertThat(new Names("red,blue,green").connectSize()).isEqualTo(2); + } + +} \ No newline at end of file From bf9ab43ca6b76052a074b2917e73bf1200d01c0f Mon Sep 17 00:00:00 2001 From: Ko Minji Date: Mon, 7 Apr 2025 11:30:22 +0900 Subject: [PATCH 11/15] style: intellij code style --- README.md | 9 +++++++ src/main/java/ladder/LadderApplication.java | 1 - .../java/ladder/domain/LadderFactory.java | 3 +-- src/main/java/ladder/domain/Line.java | 5 ++-- src/main/java/ladder/view/OutputView.java | 8 +++---- src/main/java/nextstep/fp/StreamStudy.java | 3 ++- src/main/java/nextstep/optional/User.java | 24 +++++++++---------- src/main/java/nextstep/optional/Users.java | 1 - .../java/ladder/domain/LinesFactoryTest.java | 4 ++-- .../java/nextstep/fp/StreamStudyTest.java | 3 +-- src/test/java/nextstep/optional/UserTest.java | 1 - 11 files changed, 33 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index f1b65e4eea..9d950d8ef9 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,12 @@ public class Line { [...] } ``` + +### 코멘트 +- [x] 사소하지만 컨벤션을 준수하면 좋겠네요 +- [ ] InputView > `inputNames()` 입력 책임에 맞게 이름을 리스트로 제공해 주면 어떨까요? 그러면 비즈니스 로직에서 파싱할 필요가 없어져서 로직에만 집중할 수 있습니다. +- [ ] OutputView > `printLadders()` depth가 깊어보이는데 스트림과 메소드 추출을 활용하면 좋겠습니다! +- [ ] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 +- [ ] Lines > `validLadderLength()` 양수 값 객체를 만드는 방법도 있겠네요! `규칙 6: 모든 엔티티를 작게 유지한다.` +- [ ] LadderFactory > 상태를 가지는 대신 Factory가 객체를 생성해주는 방향으로 만들어보면 어떨까요? `var ladder = factory.line(names, hieght)` +- [ ] Line > `createLine()` boolean 연산 값이 참일 때 라인 요소를 false로 세팅하네요. 가독성에 신경써서 이게 어떤 작업인지 메소드 이름을 통해 표현해 보면 좋겠습니다! \ No newline at end of file diff --git a/src/main/java/ladder/LadderApplication.java b/src/main/java/ladder/LadderApplication.java index 6d9d27b571..1309356cd0 100644 --- a/src/main/java/ladder/LadderApplication.java +++ b/src/main/java/ladder/LadderApplication.java @@ -1,7 +1,6 @@ package ladder; import ladder.domain.LadderFactory; -import ladder.domain.RandomLineGenerator; import ladder.view.InputView; import ladder.view.OutputView; diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index f1c6a7c9a4..9f8b0c0fa9 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -4,8 +4,7 @@ public class LadderFactory { private final Names names; - private final Lines lines - ; + private final Lines lines; public LadderFactory(String namesText, int height) { this(namesText, height, new RandomLineGenerator()); diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index 9e0b16e649..778e707a8a 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -2,7 +2,6 @@ import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -22,8 +21,8 @@ private static List createLine(int width, LineGenerator generator) { .mapToObj(i -> generator.isConnected()) .collect(Collectors.toList()); - for(int i=1; i names) { System.out.println("실행결과"); System.out.println(); - for(String name : names) { + for (String name : names) { System.out.print(String.format("%5s ", name)); } System.out.println(); } public void printLadders(List> ladders) { - for(List ladder : ladders) { + for (List ladder : ladders) { System.out.print(" "); - for(Boolean connected : ladder) { - if(connected) { + for (Boolean connected : ladder) { + if (connected) { System.out.print("|-----"); } else { System.out.print("| "); diff --git a/src/main/java/nextstep/fp/StreamStudy.java b/src/main/java/nextstep/fp/StreamStudy.java index b6f5146576..065dbd92d2 100644 --- a/src/main/java/nextstep/fp/StreamStudy.java +++ b/src/main/java/nextstep/fp/StreamStudy.java @@ -4,7 +4,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.*; +import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; public class StreamStudy { diff --git a/src/main/java/nextstep/optional/User.java b/src/main/java/nextstep/optional/User.java index ffad10c060..c586aec6b5 100644 --- a/src/main/java/nextstep/optional/User.java +++ b/src/main/java/nextstep/optional/User.java @@ -11,18 +11,6 @@ public User(String name, Integer age) { this.age = age; } - public String getName() { - return name; - } - - public Integer getAge() { - return age; - } - - public boolean matchName(String name) { - return this.name.equals(name); - } - public static boolean ageIsInRange1(User user) { boolean isInRange = false; @@ -41,6 +29,18 @@ public static boolean ageIsInRange2(User user) { .isPresent(); } + public String getName() { + return name; + } + + public Integer getAge() { + return age; + } + + public boolean matchName(String name) { + return this.name.equals(name); + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/nextstep/optional/Users.java b/src/main/java/nextstep/optional/Users.java index f51612fe73..ec2daa1e14 100644 --- a/src/main/java/nextstep/optional/Users.java +++ b/src/main/java/nextstep/optional/Users.java @@ -2,7 +2,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Optional; public class Users { static final User DEFAULT_USER = new User("codesquad", 100); diff --git a/src/test/java/ladder/domain/LinesFactoryTest.java b/src/test/java/ladder/domain/LinesFactoryTest.java index 2d1a65840c..a523b150b3 100644 --- a/src/test/java/ladder/domain/LinesFactoryTest.java +++ b/src/test/java/ladder/domain/LinesFactoryTest.java @@ -21,7 +21,7 @@ void validateLadderHeightShouldBeLargerThan0() { @Test @DisplayName("사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다.") void getLadder() { - assertThat(new LadderFactory("red,blue",2, () -> true).getLadder()) + assertThat(new LadderFactory("red,blue", 2, () -> true).getLadder()) .hasSize(2) .allMatch(width -> width.size() == 1); } @@ -29,7 +29,7 @@ void getLadder() { @Test @DisplayName("사다리 타기는 라인이 겹치지 않는다.") void lineShouldNotOverlap() { - assertThat(new LadderFactory("red,blue,green",3, () -> true).getLadder()) + assertThat(new LadderFactory("red,blue,green", 3, () -> true).getLadder()) .allMatch(width -> !width.equals(List.of(true, true))); } diff --git a/src/test/java/nextstep/fp/StreamStudyTest.java b/src/test/java/nextstep/fp/StreamStudyTest.java index 22478c9f9b..ab73f18445 100644 --- a/src/test/java/nextstep/fp/StreamStudyTest.java +++ b/src/test/java/nextstep/fp/StreamStudyTest.java @@ -7,7 +7,6 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Arrays; -import java.util.Comparator; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -45,7 +44,7 @@ public void printLongestWordTop100_ShouldOrderByLengthDesc() throws Exception { StreamStudy.printLongestWordTop100(); assertThat(out.toString().split(",")) .hasSize(100) - .isSortedAccordingTo((word1, word2) -> word2.length() - word1.length() ); + .isSortedAccordingTo((word1, word2) -> word2.length() - word1.length()); } @Test diff --git a/src/test/java/nextstep/optional/UserTest.java b/src/test/java/nextstep/optional/UserTest.java index b1ec7c8142..bfc6af4941 100644 --- a/src/test/java/nextstep/optional/UserTest.java +++ b/src/test/java/nextstep/optional/UserTest.java @@ -1,6 +1,5 @@ package nextstep.optional; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static nextstep.optional.User.ageIsInRange1; From 3eb4aa55fd3bea5ed8d27439be177db1ff438306 Mon Sep 17 00:00:00 2001 From: Ko Minji Date: Mon, 7 Apr 2025 11:58:49 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20OutputView=20Depth=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/ladder/LadderApplication.java | 2 +- src/main/java/ladder/view/OutputView.java | 34 ++++++++++++--------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9d950d8ef9..1a057f9684 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ public class Line { ### 코멘트 - [x] 사소하지만 컨벤션을 준수하면 좋겠네요 - [ ] InputView > `inputNames()` 입력 책임에 맞게 이름을 리스트로 제공해 주면 어떨까요? 그러면 비즈니스 로직에서 파싱할 필요가 없어져서 로직에만 집중할 수 있습니다. -- [ ] OutputView > `printLadders()` depth가 깊어보이는데 스트림과 메소드 추출을 활용하면 좋겠습니다! +- [x] OutputView > `printLadders()` depth가 깊어보이는데 스트림과 메소드 추출을 활용하면 좋겠습니다! - [ ] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 - [ ] Lines > `validLadderLength()` 양수 값 객체를 만드는 방법도 있겠네요! `규칙 6: 모든 엔티티를 작게 유지한다.` - [ ] LadderFactory > 상태를 가지는 대신 Factory가 객체를 생성해주는 방향으로 만들어보면 어떨까요? `var ladder = factory.line(names, hieght)` diff --git a/src/main/java/ladder/LadderApplication.java b/src/main/java/ladder/LadderApplication.java index 1309356cd0..9ed55512f2 100644 --- a/src/main/java/ladder/LadderApplication.java +++ b/src/main/java/ladder/LadderApplication.java @@ -13,6 +13,6 @@ public static void main(String[] args) { LadderFactory ladderFactory = new LadderFactory(inputView.inputNames(), inputView.inputHeight()); outputView.printNames(ladderFactory.getNames()); - outputView.printLadders(ladderFactory.getLadder()); + outputView.printLadder(ladderFactory.getLadder()); } } diff --git a/src/main/java/ladder/view/OutputView.java b/src/main/java/ladder/view/OutputView.java index d422ba624c..7f764bd449 100644 --- a/src/main/java/ladder/view/OutputView.java +++ b/src/main/java/ladder/view/OutputView.java @@ -1,29 +1,33 @@ package ladder.view; import java.util.List; +import java.util.stream.Collectors; public class OutputView { public void printNames(List names) { System.out.println("실행결과"); System.out.println(); - for (String name : names) { - System.out.print(String.format("%5s ", name)); - } + names.stream() + .map(name -> String.format("%5s ", name)) + .forEach(System.out::print); + System.out.println(); } - public void printLadders(List> ladders) { - for (List ladder : ladders) { - System.out.print(" "); - for (Boolean connected : ladder) { - if (connected) { - System.out.print("|-----"); - } else { - System.out.print("| "); - } - } - System.out.println("|"); - } + public void printLadder(List> ladders) { + ladders.stream() + .map(this::convertLine) + .forEach(System.out::println); + } + + private String convertLine(List line) { + return line.stream() + .map(this::convertLineElement) + .collect(Collectors.joining("|", " |", "|")); + } + + private String convertLineElement(Boolean connected) { + return Boolean.TRUE.equals(connected) ? "-----" : " "; } } From bf207756fac50bda51ee5103ad9cfc6bbb9f2bf2 Mon Sep 17 00:00:00 2001 From: Ko Minji Date: Mon, 7 Apr 2025 12:14:10 +0900 Subject: [PATCH 13/15] =?UTF-8?q?refactor:=20InputView,=20LadderFactory=20?= =?UTF-8?q?=EA=B4=80=EC=8B=AC=EC=82=AC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/ladder/domain/LadderFactory.java | 10 +++++----- src/main/java/ladder/domain/Names.java | 8 ++++++-- src/main/java/ladder/view/InputView.java | 6 ++++-- src/test/java/ladder/domain/LinesFactoryTest.java | 8 ++++---- src/test/java/ladder/domain/NamesTest.java | 6 +++--- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 1a057f9684..a226344852 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ public class Line { ### 코멘트 - [x] 사소하지만 컨벤션을 준수하면 좋겠네요 -- [ ] InputView > `inputNames()` 입력 책임에 맞게 이름을 리스트로 제공해 주면 어떨까요? 그러면 비즈니스 로직에서 파싱할 필요가 없어져서 로직에만 집중할 수 있습니다. +- [x] InputView > `inputNames()` 입력 책임에 맞게 이름을 리스트로 제공해 주면 어떨까요? 그러면 비즈니스 로직에서 파싱할 필요가 없어져서 로직에만 집중할 수 있습니다. - [x] OutputView > `printLadders()` depth가 깊어보이는데 스트림과 메소드 추출을 활용하면 좋겠습니다! - [ ] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 - [ ] Lines > `validLadderLength()` 양수 값 객체를 만드는 방법도 있겠네요! `규칙 6: 모든 엔티티를 작게 유지한다.` diff --git a/src/main/java/ladder/domain/LadderFactory.java b/src/main/java/ladder/domain/LadderFactory.java index 9f8b0c0fa9..6847be0f22 100644 --- a/src/main/java/ladder/domain/LadderFactory.java +++ b/src/main/java/ladder/domain/LadderFactory.java @@ -6,13 +6,13 @@ public class LadderFactory { private final Names names; private final Lines lines; - public LadderFactory(String namesText, int height) { - this(namesText, height, new RandomLineGenerator()); + public LadderFactory(List names, int height) { + this(names, height, new RandomLineGenerator()); } - public LadderFactory(String namesText, int height, LineGenerator lineGenerator) { - this.names = new Names(namesText); - this.lines = new Lines(height, names.connectSize(), lineGenerator); + public LadderFactory(List names, int height, LineGenerator lineGenerator) { + this.names = new Names(names); + this.lines = new Lines(height, this.names.connectSize(), lineGenerator); } public List> getLadder() { diff --git a/src/main/java/ladder/domain/Names.java b/src/main/java/ladder/domain/Names.java index ed9d7c3c33..1fcc3719fa 100644 --- a/src/main/java/ladder/domain/Names.java +++ b/src/main/java/ladder/domain/Names.java @@ -7,8 +7,12 @@ public class Names { private final List names; - public Names(String text) { - this.names = Arrays.asList(text.split(",")); + public Names(String... names) { + this(Arrays.asList(names)); + } + + public Names(List names) { + this.names = names; validateNameMaxLength(names); } diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java index 64312afa50..39daa87b3c 100644 --- a/src/main/java/ladder/view/InputView.java +++ b/src/main/java/ladder/view/InputView.java @@ -1,15 +1,17 @@ package ladder.view; +import java.util.Arrays; +import java.util.List; import java.util.Scanner; public class InputView { private static final Scanner SCANNER = new Scanner(System.in); - public String inputNames() { + public List inputNames() { System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); String names = SCANNER.nextLine(); System.out.println(); - return names; + return Arrays.asList(names.split(",")); } public int inputHeight() { diff --git a/src/test/java/ladder/domain/LinesFactoryTest.java b/src/test/java/ladder/domain/LinesFactoryTest.java index a523b150b3..b18250ae10 100644 --- a/src/test/java/ladder/domain/LinesFactoryTest.java +++ b/src/test/java/ladder/domain/LinesFactoryTest.java @@ -14,14 +14,14 @@ class LinesFactoryTest { @Test @DisplayName("사다리 게임에 입력하는 사다리 높이는 양수여야 한다.") void validateLadderHeightShouldBeLargerThan0() { - assertThatThrownBy(() -> new LadderFactory("sunny,univ", -1)) + assertThatThrownBy(() -> new LadderFactory(List.of("sunny", "univ"), -1)) .isInstanceOf(IllegalArgumentException.class); } @Test @DisplayName("사다리 타기는 (참여하는 사람의 수 - 1) 만큼 라인이 생성된다.") void getLadder() { - assertThat(new LadderFactory("red,blue", 2, () -> true).getLadder()) + assertThat(new LadderFactory(List.of("red", "blue"), 2, () -> true).getLadder()) .hasSize(2) .allMatch(width -> width.size() == 1); } @@ -29,14 +29,14 @@ void getLadder() { @Test @DisplayName("사다리 타기는 라인이 겹치지 않는다.") void lineShouldNotOverlap() { - assertThat(new LadderFactory("red,blue,green", 3, () -> true).getLadder()) + assertThat(new LadderFactory(List.of("red", "blue", "green"), 3, () -> true).getLadder()) .allMatch(width -> !width.equals(List.of(true, true))); } @Test @DisplayName("사다리 타기 참여자의 이름을 얻는다.") void getNames() { - assertThat(new LadderFactory("red,blue,green", 1).getNames()).contains("red", "blue", "green"); + assertThat(new LadderFactory(List.of("red", "blue", "green"), 1).getNames()).contains("red", "blue", "green"); } } diff --git a/src/test/java/ladder/domain/NamesTest.java b/src/test/java/ladder/domain/NamesTest.java index da1a3be0e4..8949e3f85e 100644 --- a/src/test/java/ladder/domain/NamesTest.java +++ b/src/test/java/ladder/domain/NamesTest.java @@ -11,20 +11,20 @@ class NamesTest { @Test @DisplayName("참여자 이름이 최대 글자수를 초과하면 에러가 발생한다.") void exceedNameLengthLimit() { - assertThatThrownBy(() -> new Names("sunny,universe")) + assertThatThrownBy(() -> new Names("sunny", "universe")) .isInstanceOf(IllegalArgumentException.class); } @Test @DisplayName("참여자 이름이 들어간 리스트가 반환된다.") void getAllNames() { - assertThat(new Names("red,blue,green").getAll()).contains("red", "blue", "green"); + assertThat(new Names("red", "blue", "green").getAll()).contains("red", "blue", "green"); } @Test @DisplayName("참여자 사이의 연결 개수를 반환한다.") void getConnectSize() { - assertThat(new Names("red,blue,green").connectSize()).isEqualTo(2); + assertThat(new Names("red", "blue", "green").connectSize()).isEqualTo(2); } } \ No newline at end of file From 10bee83bcdeec284e130f997c97749cf6feaede8 Mon Sep 17 00:00:00 2001 From: Ko Minji Date: Mon, 7 Apr 2025 12:26:04 +0900 Subject: [PATCH 14/15] =?UTF-8?q?refactor:=20Line=20equals,=20hashcode=20?= =?UTF-8?q?=EC=9E=AC=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/ladder/domain/Line.java | 23 +++++++++++++++++++++++ src/test/java/ladder/domain/LineTest.java | 4 ++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a226344852..27909dd50e 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ public class Line { - [x] 사소하지만 컨벤션을 준수하면 좋겠네요 - [x] InputView > `inputNames()` 입력 책임에 맞게 이름을 리스트로 제공해 주면 어떨까요? 그러면 비즈니스 로직에서 파싱할 필요가 없어져서 로직에만 집중할 수 있습니다. - [x] OutputView > `printLadders()` depth가 깊어보이는데 스트림과 메소드 추출을 활용하면 좋겠습니다! -- [ ] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 +- [x] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 - [ ] Lines > `validLadderLength()` 양수 값 객체를 만드는 방법도 있겠네요! `규칙 6: 모든 엔티티를 작게 유지한다.` - [ ] LadderFactory > 상태를 가지는 대신 Factory가 객체를 생성해주는 방향으로 만들어보면 어떨까요? `var ladder = factory.line(names, hieght)` - [ ] Line > `createLine()` boolean 연산 값이 참일 때 라인 요소를 false로 세팅하네요. 가독성에 신경써서 이게 어떤 작업인지 메소드 이름을 통해 표현해 보면 좋겠습니다! \ No newline at end of file diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index 778e707a8a..3984303f9e 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -2,6 +2,7 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -12,10 +13,20 @@ public Line(int width, LineGenerator generator) { this(createLine(width, generator)); } + public Line(boolean... line) { + this(boxed(line)); + } + public Line(List line) { this.line = line; } + private static List boxed(boolean[] line) { + return IntStream.range(0, line.length) + .mapToObj(i -> line[i]) + .collect(Collectors.toList()); + } + private static List createLine(int width, LineGenerator generator) { List lines = IntStream.range(0, width) .mapToObj(i -> generator.isConnected()) @@ -33,4 +44,16 @@ public List getList() { return Collections.unmodifiableList(line); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Line line1 = (Line) o; + return Objects.equals(line, line1.line); + } + + @Override + public int hashCode() { + return Objects.hashCode(line); + } } diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java index ba93545283..26f0c81f91 100644 --- a/src/test/java/ladder/domain/LineTest.java +++ b/src/test/java/ladder/domain/LineTest.java @@ -12,8 +12,8 @@ class LineTest { @Test @DisplayName("사다리 라인을 생성한다.") void createLine() { - assertThat(new Line(3, () -> true).getList()).isEqualTo(List.of(true, false, true)); - assertThat(new Line(3, () -> false).getList()).isEqualTo(List.of(false, false, false)); + assertThat(new Line(3, () -> true)).isEqualTo(new Line(true, false, true)); + assertThat(new Line(3, () -> false)).isEqualTo(new Line(false, false, false)); } @Test From e283d758bd3aa81935894ae46539f3e6bf41e145 Mon Sep 17 00:00:00 2001 From: Ko Minji Date: Mon, 7 Apr 2025 18:18:34 +0900 Subject: [PATCH 15/15] =?UTF-8?q?refactor:=20Line.createLine=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/ladder/domain/Line.java | 32 ++++++++++++++--------- src/test/java/ladder/domain/LineTest.java | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 27909dd50e..d9e273e68d 100644 --- a/README.md +++ b/README.md @@ -143,4 +143,4 @@ public class Line { - [x] LineTest > `getLine()` 대신 `new Line()`으로 비교해 볼 수 있게 만들어봐도 좋겠네요 - [ ] Lines > `validLadderLength()` 양수 값 객체를 만드는 방법도 있겠네요! `규칙 6: 모든 엔티티를 작게 유지한다.` - [ ] LadderFactory > 상태를 가지는 대신 Factory가 객체를 생성해주는 방향으로 만들어보면 어떨까요? `var ladder = factory.line(names, hieght)` -- [ ] Line > `createLine()` boolean 연산 값이 참일 때 라인 요소를 false로 세팅하네요. 가독성에 신경써서 이게 어떤 작업인지 메소드 이름을 통해 표현해 보면 좋겠습니다! \ No newline at end of file +- [x] Line > `createLine()` boolean 연산 값이 참일 때 라인 요소를 false로 세팅하네요. 가독성에 신경써서 이게 어떤 작업인지 메소드 이름을 통해 표현해 보면 좋겠습니다! \ No newline at end of file diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index 3984303f9e..7f317bc4f4 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -9,35 +9,40 @@ public class Line { private final List line; - public Line(int width, LineGenerator generator) { - this(createLine(width, generator)); + public Line(int size, LineGenerator generator) { + this(createLine(size, generator)); } public Line(boolean... line) { - this(boxed(line)); + this(createLine(line)); } public Line(List line) { this.line = line; } - private static List boxed(boolean[] line) { + private static List createLine(int size, LineGenerator generator) { + if (size < 1) { + throw new IllegalArgumentException("Line size should be greater than 0"); + } + return createLine(generate(size, generator)); + } + + private static List createLine(boolean[] line) { return IntStream.range(0, line.length) .mapToObj(i -> line[i]) .collect(Collectors.toList()); } - private static List createLine(int width, LineGenerator generator) { - List lines = IntStream.range(0, width) - .mapToObj(i -> generator.isConnected()) - .collect(Collectors.toList()); + private static boolean[] generate(int size, LineGenerator generator) { + boolean[] line = new boolean[size]; + line[0] = generator.isConnected(); - for (int i = 1; i < width; i++) { - if (lines.get(i - 1) && lines.get(i)) { - lines.set(i, false); - } + for (int i = 1; i < size; i++) { + line[i] = (!line[i - 1] && generator.isConnected()); } - return lines; + + return line; } public List getList() { @@ -56,4 +61,5 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(line); } + } diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java index 26f0c81f91..da27989ac2 100644 --- a/src/test/java/ladder/domain/LineTest.java +++ b/src/test/java/ladder/domain/LineTest.java @@ -19,7 +19,7 @@ void createLine() { @Test @DisplayName("사다리의 라인 하나가 반환된다.") void getList() { - assertThat(new Line(List.of(true, false, true)).getList()).isEqualTo(List.of(true, false, true)); + assertThat(new Line(true, false, true).getList()).isEqualTo(List.of(true, false, true)); } } \ No newline at end of file