-
Notifications
You must be signed in to change notification settings - Fork 709
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단계 - 사다리(생성) #1562
base: yerin-158
Are you sure you want to change the base?
2단계 - 사다리(생성) #1562
Changes from all commits
d2165e2
b1c82f5
1ff12a8
23a65d2
3e6c132
089fa54
d2d9e98
059a290
967eb85
2268c3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package ladderapplication; | ||
|
||
import ladderapplication.models.Ladder; | ||
import ladderapplication.models.requests.GameSettingRequest; | ||
import ladderapplication.ui.Printer; | ||
|
||
public class LadderApplication { | ||
|
||
public static void main(String[] args) { | ||
GameSettingRequest gameSettingRequest = Printer.requestGameSetting(); | ||
|
||
Ladder ladder = Ladder.from(gameSettingRequest); | ||
ladder.print(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package ladderapplication.models; | ||
|
||
import ladderapplication.models.requests.GameSettingRequest; | ||
import ladderapplication.utils.DecoratingUtils; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class Ladder { | ||
|
||
private final List<Player> players; | ||
private final List<Line> lines; | ||
private final String drawing; | ||
|
||
private Ladder(List<Player> players, List<Line> lines, String drawing) { | ||
this.players = players; | ||
this.lines = lines; | ||
this.drawing = drawing; | ||
} | ||
|
||
public static Ladder from(GameSettingRequest gameSettingRequest) { | ||
List<Player> newPlayers = gameSettingRequest.getPlayerRequests() | ||
.stream() | ||
.map(Player::from) | ||
.collect(Collectors.toList()); | ||
|
||
int playerCount = gameSettingRequest.getPlayerRequests().size(); | ||
int ladderHeight = gameSettingRequest.getLadderRequest().getHeight(); | ||
List<Line> newLines = Stream.generate(() -> Line.of(playerCount)) | ||
.limit(ladderHeight) | ||
.collect(Collectors.toList()); | ||
Comment on lines
+22
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 위 내용을 개선하면 사다리 생성에 있어서 불필요한 로직들도 분리될거에요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GameSettingRequest는 client의 입력을 가지는 객체인데요, 필요한 정보만을 넘기는것은 어떨까요? (추가로 테스트 코드 작성하실때도 불편하시지 않았나요?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 테스트코드가 없군요! |
||
|
||
String drawing = createDrawing(newPlayers, newLines); | ||
return new Ladder(newPlayers, newLines, drawing); | ||
} | ||
|
||
private static String createDrawing(List<Player> players, List<Line> lines) { | ||
StringBuilder sb = new StringBuilder(); | ||
addPlayerNames(sb, players); | ||
addLines(sb, lines); | ||
return sb.toString(); | ||
} | ||
Comment on lines
+38
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 도메인이 뷰에 대한 책임까지 가지고있는 구조가 맞을까요? |
||
|
||
private static void addPlayerNames(StringBuilder sb, List<Player> players) { | ||
players.forEach(player -> sb.append(DecoratingUtils.getDecoratedName(player.getName()))); | ||
sb.append("\n"); | ||
} | ||
|
||
private static void addLines(StringBuilder sb, List<Line> lines) { | ||
lines.forEach(line -> sb.append(line.print()).append("\n")); | ||
} | ||
|
||
public void print() { | ||
System.out.println(this.drawing); | ||
} | ||
Comment on lines
+54
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런부분들도 view쪽에서 담당하게 해보면 어떨까요? |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package ladderapplication.models; | ||
|
||
import ladderapplication.utils.DecoratingUtils; | ||
|
||
import java.util.List; | ||
import java.util.Random; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
import java.util.stream.Stream; | ||
|
||
public class Line { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 각 도메인에 대한 테스트도 꼭 작성해주셔요! |
||
private static final Random RANDOM_GENERATOR = new Random(); | ||
private static final int HAS_STEP_BOUND = 4; | ||
private static final int RANDOM_NUMBER_BOUND = 10; | ||
private final List<Boolean> hasSteps; | ||
|
||
private Line(List<Boolean> hasSteps) { | ||
this.hasSteps = hasSteps; | ||
} | ||
|
||
public static Line of(int playerCount) { | ||
List<Boolean> hasSteps = Stream.generate(() -> Boolean.FALSE) | ||
.limit(playerCount - 1) | ||
.collect(Collectors.toList()); | ||
|
||
IntStream.range(0, hasSteps.size()) | ||
.forEach(index -> setHasStep(hasSteps, index)); | ||
|
||
return new Line(hasSteps); | ||
} | ||
|
||
private static void setHasStep(List<Boolean> hasSteps, int index) { | ||
if (prevLadderHasNotStep(hasSteps, index) && hasStep()) { | ||
hasSteps.set(index, Boolean.TRUE); | ||
} | ||
} | ||
|
||
private static boolean prevLadderHasNotStep(List<Boolean> hasSteps, int index) { | ||
return index == 0 || !hasSteps.get(index - 1); | ||
} | ||
|
||
private static boolean hasStep() { | ||
return RANDOM_GENERATOR.nextInt(RANDOM_NUMBER_BOUND) >= HAS_STEP_BOUND; | ||
} | ||
|
||
public String print() { | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append(" "); | ||
hasSteps.forEach(hasStep -> { | ||
Comment on lines
+46
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ladder쪽과 같은 내용이에요~ 책임분리를 해보아요! |
||
sb.append("|") | ||
.append(DecoratingUtils.getStep(hasStep)); | ||
}); | ||
|
||
sb.append("|"); | ||
return sb.toString(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package ladderapplication.models; | ||
|
||
import ladderapplication.models.requests.PlayerRequest; | ||
|
||
public class Player { | ||
|
||
private final String name; | ||
|
||
private Player(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public static Player from(PlayerRequest playerRequest) { | ||
return new Player(playerRequest.getName()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package ladderapplication.models.requests; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. requests 패키지 위치도 도메인 하위가 아닌 최소한 같은 레벨로 올려야하지 않을까요? |
||
|
||
import java.util.List; | ||
|
||
public class GameSettingRequest { | ||
|
||
private final LadderRequest ladderRequest; | ||
private final List<PlayerRequest> playerRequests; | ||
|
||
private GameSettingRequest(LadderRequest ladderRequest, List<PlayerRequest> playerRequests) { | ||
this.ladderRequest = ladderRequest; | ||
this.playerRequests = playerRequests; | ||
} | ||
|
||
public LadderRequest getLadderRequest() { | ||
return ladderRequest; | ||
} | ||
|
||
public List<PlayerRequest> getPlayerRequests() { | ||
return playerRequests; | ||
} | ||
|
||
public static GameSettingRequest of(LadderRequest ladderRequest, List<PlayerRequest> playerRequests) { | ||
return new GameSettingRequest(ladderRequest, playerRequests); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package ladderapplication.models.requests; | ||
|
||
public class LadderRequest { | ||
|
||
private final int height; | ||
|
||
private LadderRequest(int height) { | ||
this.height = height; | ||
} | ||
|
||
public int getHeight() { | ||
return height; | ||
} | ||
|
||
public static LadderRequest of(int height) { | ||
return new LadderRequest(height); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package ladderapplication.models.requests; | ||
|
||
public class PlayerRequest { | ||
|
||
private final String name; | ||
|
||
private PlayerRequest(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public static PlayerRequest of(String name) { | ||
return new PlayerRequest(name); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package ladderapplication.ui; | ||
|
||
import java.util.Scanner; | ||
|
||
public class InputScanner { | ||
|
||
private static final Scanner SCANNER = new Scanner(System.in); | ||
|
||
public static String stringScan() { | ||
return SCANNER.nextLine(); | ||
} | ||
|
||
public static int intScan() { | ||
return SCANNER.nextInt(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package ladderapplication.ui; | ||
|
||
import ladderapplication.models.requests.GameSettingRequest; | ||
import ladderapplication.models.requests.LadderRequest; | ||
import ladderapplication.models.requests.PlayerRequest; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class Printer { | ||
|
||
public static GameSettingRequest requestGameSetting() { | ||
System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); | ||
String players = InputScanner.stringScan(); | ||
String[] playerArr = players.split(","); | ||
List<PlayerRequest> playerRequests = Stream.of(playerArr).map(PlayerRequest::of).collect(Collectors.toList()); | ||
|
||
System.out.println("최대 사다리 높이는 몇 개인가요?"); | ||
int height = InputScanner.intScan(); | ||
LadderRequest ladderRequest = LadderRequest.of(height); | ||
|
||
return GameSettingRequest.of(ladderRequest, playerRequests); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package ladderapplication.utils; | ||
|
||
public class DecoratingUtils { | ||
|
||
private static final String EMPTY = " "; | ||
private static final String STEP_PIECE = "-"; | ||
private static final int NAME_SPACE = 6; | ||
private static final int STANDARD_SIZE = 4; | ||
private static final int STEP_LENGTH = 5; | ||
|
||
public static String getDecoratedName(String name) { | ||
StringBuilder sb = new StringBuilder(); | ||
if (name.length() < STANDARD_SIZE) { | ||
sb.append(getRepeatCharacter(EMPTY, STANDARD_SIZE - name.length())); | ||
} | ||
sb.append(name) | ||
.append(getRepeatCharacter(EMPTY, NAME_SPACE - sb.length())); | ||
return sb.toString(); | ||
} | ||
|
||
private static String getRepeatCharacter(String character, int repeatCount) { | ||
return character.repeat(repeatCount); | ||
} | ||
|
||
public static String getStep(boolean hasStep) { | ||
if (hasStep) { | ||
return getRepeatCharacter(STEP_PIECE, STEP_LENGTH); | ||
} | ||
|
||
return getRepeatCharacter(EMPTY, STEP_LENGTH); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package ladderapplication.validator; | ||
|
||
import ladderapplication.models.requests.PlayerRequest; | ||
|
||
public class PlayerRequestValidator { | ||
|
||
private static final String WRONG_NAME = "플레이어 이름음 5글자 이하 여야 합니다."; | ||
|
||
public static void validation(PlayerRequest playerRequest) { | ||
if (playerRequest.getName().length() > 5) { | ||
throw new IllegalArgumentException(WRONG_NAME); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package ladderapplication.validator; | ||
|
||
import ladderapplication.models.requests.PlayerRequest; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
class PlayerRequestValidatorTest { | ||
|
||
private static final String WRONG_NAME = "플레이어 이름음 5글자 이하 여야 합니다."; | ||
private static final List<PlayerRequest> playerRequests = new ArrayList<>(); | ||
|
||
@BeforeAll | ||
public static void setPlayerRequest() { | ||
String players = "pobi,honux,crong,jk"; | ||
String[] playerArr = players.split(","); | ||
Stream.of(playerArr).forEach(name -> playerRequests.add(PlayerRequest.of(name))); | ||
} | ||
|
||
@Test | ||
@DisplayName("입력받은 사용자 이름이 5글자가 넘으면 Exception이 발생한다.") | ||
void test1() { | ||
PlayerRequest playerRequest = PlayerRequest.of("robinson"); | ||
Exception exception = assertThrows(IllegalArgumentException.class, () -> PlayerRequestValidator.validation(playerRequest)); | ||
assertThat(exception.getMessage()).isEqualTo(WRONG_NAME); | ||
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사다리 객체에 필요한 정보가 어떤것인지 정리가 필요할거같아요~
필요한 최소의 정보만을 유지하는게 어떨까요? 불필요한 필드를 가짐으로써 응집력이 낮아져 유지보수를 힘들게 할 수 있습니다.