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

Step2, 3 #1813

Open
wants to merge 3 commits into
base: 201411167
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ repositories {
}

dependencies {
implementation 'org.projectlombok:lombok:1.18.26'
annotationProcessor 'org.projectlombok:lombok:1.18.26'
testImplementation 'org.assertj:assertj-core:3.22.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
}
Expand Down
31 changes: 5 additions & 26 deletions src/main/java/nextstep/fp/Lambda.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,10 @@ public void run() {
}).start();
}

public static int sumAll(List<Integer> numbers) {
int total = 0;
for (int number : numbers) {
total += number;
}
return total;
}

public static int sumAllEven(List<Integer> numbers) {
int total = 0;
for (int number : numbers) {
if (number % 2 == 0) {
total += number;
}
}
return total;
}

public static int sumAllOverThree(List<Integer> numbers) {
int total = 0;
for (int number : numbers) {
if (number > 3) {
total += number;
}
}
return total;
public static int sumAll(List<Integer> numbers, SumStrategy sumStrategy) {
return numbers.stream()
.filter(sumStrategy::option)
.mapToInt(value -> value)
.sum();
}
}
20 changes: 13 additions & 7 deletions src/main/java/nextstep/fp/StreamStudy.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -15,19 +16,21 @@ public static long countWords() throws IOException {
.get("src/main/resources/fp/war-and-peace.txt")), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contents.split("[\\P{L}]+"));

long count = 0;
for (String w : words) {
if (w.length() > 12) count++;
}
return count;
return words.stream()
.filter(w -> w.length() > 12)
.count();
}

public static void printLongestWordTop100() throws IOException {
String contents = new String(Files.readAllBytes(Paths
.get("src/main/resources/fp/war-and-peace.txt")), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contents.split("[\\P{L}]+"));

// TODO 이 부분에 구현한다.
words.stream()
.filter(w -> w.length() > 12) // 단어 길이 12 이상
.sorted((o1, o2) -> o2.length() - o1.length()) // 긴 순서
.distinct()
.forEach(s -> System.out.println(s.toLowerCase()));
}

public static List<Integer> doubleNumbers(List<Integer> numbers) {
Expand All @@ -39,6 +42,9 @@ public static long sumAll(List<Integer> numbers) {
}

public static long sumOverThreeAndDouble(List<Integer> numbers) {
return 0;
return numbers.stream()
.filter(i -> i > 3)
.map(i -> 2 * i)
.reduce(0, (x, y) -> x + y);
}
}
5 changes: 5 additions & 0 deletions src/main/java/nextstep/fp/SumStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nextstep.fp;

public interface SumStrategy {
boolean option(int number);
}
41 changes: 41 additions & 0 deletions src/main/java/nextstep/ladder/LadderApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package nextstep.ladder;

import nextstep.ladder.domain.Ladder;
import nextstep.ladder.domain.LadderResults;
import nextstep.ladder.domain.User;
import nextstep.ladder.domain.Users;
import nextstep.ladder.view.InputView;
import nextstep.ladder.view.OutputView;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class LadderApplication {

public static void main(String[] args) {

Choose a reason for hiding this comment

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

메서드 라인 수가 길어 보이는데, 자동차 경주 미션 때처럼 메서드의 라인 수를 줄여보면 어떨까요?
이 같은 원칙 아래에서 메소드의 라인 수를 15라인이 넘지 않도록 구현한다.


List<String> names = InputView.inputUserNames();
Users users = new Users(names);

List<String> results = InputView.inputLadderResult();
LadderResults ladderResults = new LadderResults(results);

int height = InputView.inputLadderHeight();

Ladder ladder = Ladder.createLadder(users.getUsers().size(), height, () -> new Random().nextBoolean());
OutputView.display(users, ladder, ladderResults);

List<User> usersAfter = users.getUsers().stream()
.map(user -> user.rideLadder(ladder))
.collect(Collectors.toList());
Comment on lines +29 to +31

Choose a reason for hiding this comment

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

getter로 값을 꺼내서 처리하는 대신에, 메시지를 보내는 방식으로 처리해보면 어떨까요?


String name = InputView.inputUserName();

if (name.equals("all")) {
OutputView.announceAllUsers(usersAfter, ladderResults);
return;
}
OutputView.announceUser(name, usersAfter, ladderResults);
Comment on lines +35 to +39

Choose a reason for hiding this comment

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

해당 로직은 OutputView 내부로 옮겨보면 어떨까요?

}
}
6 changes: 6 additions & 0 deletions src/main/java/nextstep/ladder/domain/BridgeStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package nextstep.ladder.domain;

@FunctionalInterface
public interface BridgeStrategy {
Boolean bridgeBuild();

Choose a reason for hiding this comment

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

  • wrapper 클래스를 사용하신 이유가 있으실까요?
  • BridgeStrategy라는 이름을 통해 Bridge를 생성하는 전략임을 유추할 수 있기 때문에,
    메서드 이름은 build() 정도로 지어도 충분히 의미를 전달할 수 있을 것 같습니다.

}
44 changes: 44 additions & 0 deletions src/main/java/nextstep/ladder/domain/Ladder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package nextstep.ladder.domain;

import lombok.Getter;

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

@Getter
public class Ladder {
private List<Line> lines = new ArrayList<>();

public static Ladder createLadder(int countOfUsers, int height, BridgeStrategy strategy) {
return new Ladder(countOfUsers, height, strategy);
}

private Ladder(int countOfUsers, int height, BridgeStrategy strategy) {
for (int i = 0; i < height; i++) {
Line line = Line.createLine(countOfUsers, strategy);
lines.add(line);
}
}
Comment on lines +12 to +21

Choose a reason for hiding this comment

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

다음 클래스 작성 순서 가이드를 참고해보시면 좋을 것 같습니다.
https://www.oracle.com/java/technologies/javase/codeconventions-fileorganization.html


public String status() {
String result = "";
int height = lines.size();
for (int i = 0; i < height; i++) {
Line line = lines.get(i);
result += line.status();
}
return result;
}

public int findLastPosition(int position) {
if (lines.isEmpty()) {
return position;
}

int currentPosition = position;
for (Line line : lines) {
currentPosition = line.getNextPosition(currentPosition);
}
return currentPosition;
}
}
10 changes: 10 additions & 0 deletions src/main/java/nextstep/ladder/domain/LadderResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nextstep.ladder.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class LadderResult {
private String result;
}
25 changes: 25 additions & 0 deletions src/main/java/nextstep/ladder/domain/LadderResults.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nextstep.ladder.domain;

import lombok.Getter;

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

@Getter
public class LadderResults {
private List<LadderResult> ladderResultList = new ArrayList<>();

public LadderResults(List<String> results) {
for (String result : results) {
ladderResultList.add(new LadderResult(result));
}
}

public String status() {
String result = "";
for (LadderResult ladderResult : ladderResultList) {
result += ladderResult.getResult() + " ";
}
return result;
}
}
109 changes: 109 additions & 0 deletions src/main/java/nextstep/ladder/domain/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package nextstep.ladder.domain;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Getter
public class Line {

private List<Boolean> bridges = new ArrayList<>();

public static Line createLine(int countOfPerson, BridgeStrategy strategy) {
Line line = new Line(countOfPerson, strategy);
validate(line);
return line;
}

private static void validate(Line line) {
if (line.isInvalidBridge()) {
throw new RuntimeException("올바르지 않은 라인입니다.");
}
}

private Line(int countOfPerson, BridgeStrategy strategy) {
for (int i = 0; i < countOfPerson - 1; i++) {
Optional<Integer> prevIndex = Optional.ofNullable(i)
.map(o -> o - 1);

Boolean expected = build(strategy);
bridges.add(decide(prevIndex, expected));
}
}

private static Boolean build(BridgeStrategy strategy) {
return strategy.bridgeBuild();
}

private Boolean decide(Optional<Integer> prevIndex, Boolean expected) {

Choose a reason for hiding this comment

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

매개변수의 타입으로 Optional이 사용되고 있는데, 다음 링크를 참고해보시면 좋을 것 같습니다.
https://yeonyeon.tistory.com/224

return prevIndex.filter(i -> i >= 0)
.map(i -> bridges.get(i))
.map(b -> Boolean.TRUE.equals(b) ? Boolean.valueOf(false) : expected)

Choose a reason for hiding this comment

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

이번 교육과정에서는 삼항 연산자도 if-else의 축약형이라고 보기 때문에, 사용을 지양하시는 걸 추천 드립니다.

.orElse(expected);
}

public int getNextPosition(int position) {

Choose a reason for hiding this comment

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

해당 메서드의 라인 수도 줄여보면 좋을 것 같습니다.

// bridges[position - 1] == T 이면 왼쪽으로
Boolean toLeft = ableToLeft(position);

// bridges[position] == T 이면 오른쪽으로
Boolean toRight = ableToRight(position);

if (toLeft && toRight) {
throw new RuntimeException("사다리 상태를 다시 확인해주세요.");
}

if (toLeft) {
return position - 1;
}

if (toRight) {
return position + 1;
}

return position;
}

public Boolean ableToRight(int position) {
return Optional.ofNullable(position)
.filter(o -> o < bridges.size())
.map(o -> bridges.get(o))
.filter(b -> b)
.orElse(false);
}

public Boolean ableToLeft(int position) {
return Optional.ofNullable(position)
.map(o -> o - 1)
.filter(o -> o >= 0)
.map(o -> bridges.get(o))
.filter(b -> b)
.orElse(false);
}

public boolean isValidBridge() {
boolean valid = true;
for (int i = 0; i < bridges.size(); i++) {
if (ableToLeft(i) && ableToRight(i)) {
valid = false;
}
}
Comment on lines +88 to +92

Choose a reason for hiding this comment

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

for 안에 if가 중첩되어 들여쓰기 단계가 2인데, 들여쓰기 단계를 1로 줄여보면 어떨까요?

return valid;
}
public boolean isInvalidBridge() {
return !isValidBridge();
}


public String status() {

Choose a reason for hiding this comment

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

도메인 객체 내부에 view와 관련된 로직이 포함되어 있어서, 도메인이 view에 의존하는 관계라고 볼 수 있습니다.
view와 관련된 로직은 view 내부로 옮겨보는 건 어떨까요?

String result = "";
for (Boolean bridge : bridges) {
result += "|";
result += bridge ? "-----" : " ";
}
result += "|\n";
return result;
}
}
31 changes: 31 additions & 0 deletions src/main/java/nextstep/ladder/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package nextstep.ladder.domain;

import lombok.Getter;

@Getter
public class User {
private String name;
private int position;


public User(String name, int position) {
validateName(name);

this.name = name;
this.position = position;
}

private static void validateName(String name) {
if (name.length() > 5) {
throw new IllegalArgumentException("이름은 5글자까지 가능합니다.");
}
if (name.equals("all")) {
throw new IllegalArgumentException("all은 부적절한 이름입니다.");
}
Comment on lines +19 to +24

Choose a reason for hiding this comment

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

5, all과 같은 숫자, 문자 리터럴 등은 상수로 선언하여 의미를 부여해보면 어떨까요?
상수로 정의해두면 예외 메시지를 작성할 때도 하드 코딩하는 대신에 해당 상수를 재활용해볼 수 있을 것 같아요.

}

public User rideLadder(Ladder ladder) {
int lastPosition = ladder.findLastPosition(position);
return new User(name, lastPosition);
}
}
26 changes: 26 additions & 0 deletions src/main/java/nextstep/ladder/domain/Users.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package nextstep.ladder.domain;

import lombok.Getter;

import java.util.*;
import java.util.stream.Collectors;

@Getter
public class Users {
private List<User> users = new ArrayList<>();

public Users(List<String> names) {
for (int i = 0; i < names.size(); i++) {
User user = new User(names.get(i), i);
users.add(user);
}
}

public String status() {
String result = "";
for (User user : users) {
result += user.getName() + " ";
}
return result;
}
}
Loading