[사다리 게임] 진영, 상엽 - 기능 구현 (without refactoring)#1
[사다리 게임] 진영, 상엽 - 기능 구현 (without refactoring)#1kanamycine wants to merge 35 commits intosproutt:jinyeongchoifrom
Conversation
- matchingLine : 한줄씩 사다리 체크
- makeLine() : 2차원 배열 취급 -> 1차원 배열 생성 역할 위임 - makeBridge() : 조건에 따라 다리 생성 로직 분리
- Dto로 감싸서 outputView에 전달
- 조건식 단순화 - 매직넘버 상수 처리
- (int height) -> (Height Height)
- LadderBluePrintDto -> LinesDto
- Game 로직 수정
- Players에 있던 render 메서드 뷰에 위임
- outputView dto 형식에 맞게 수정
- resultAll dto 구현 Map<Player, ExecutionResult> -> Map <String, String>
- getter 추가
- LadderMakerTest - NameTest - PlayersTest
GiPyoo
left a comment
There was a problem hiding this comment.
👍 제가 하는 질문은 정답이 있는 것은 아닙니다... 제가 JAVA 문법이 짧아서 깊이있는 리뷰는 못해 드려서 죄송합니다.
| // ladder 로직 Ladder.makeLadder(payers, executionResults); | ||
| int ladderHeight = inputView.inputLadderHeight(); | ||
| LadderMaker lm = new LadderMaker(ladderHeight); | ||
| Ladder ladder = lm.makeLadder(players.getPlayers().size()); |
There was a problem hiding this comment.
size를 구하는 것을 Players 내부 메서드를 만들지 않고 get을 한 후 이처럼 List 내장 메서드인 size를 사용하신 이유가 궁금합니다.
OOP를 배웠을 때, class의 경우 자신이 할 수 있는 일들은 내부적으로 가지는 것이 좋다고 들어서 편의성 때문인지? 궁금해서 질문합니다.
src/main/java/src/model/Referee.java
Outdated
| for (int i = 0; i < players.getPlayers().size(); i++) { | ||
| map.put(players.getPlayers().get(i).getName(), |
There was a problem hiding this comment.
요것도 비슷합니당 => players.getPlayers().size()
추가 : players.getPlayers().get(i).getName() 이 부분도 바꿔볼 수 있는 점이 있는 것 같은데용, 체이닝을 의도하신 것인지 궁금합니다.
hyukjin-lee
left a comment
There was a problem hiding this comment.
어려운 요구사항이었을텐데 페어도 바꿔가면서 진행하느라 고생하셨습니다~
중요한 비즈니스 로직들에 대한 테스트가 없어서 조금 아쉽고 코드가 아직 정리가 안된 상태로 올라온 것 같아서 요구사항이 정상적으로 돌아갈 정도로는 정리가 필요해보입니다 ~
수고하셨습니다
| @@ -0,0 +1,185 @@ | |||
| #!/usr/bin/env sh | |||
|
|
||
| private static final String RESULT_ALL_INPUT_MESSAGE = "all"; | ||
|
|
||
| private InputView inputView; |
There was a problem hiding this comment.
View 클래스를 유틸성 클래스로 정의하고 static 메서드들을 활용해보면 어떨까요?
| } | ||
|
|
||
| public void start() { | ||
| // inputPlayers , inputExecutionResults로 쪼개야 하는지는 조금 더 고민 |
There was a problem hiding this comment.
고민이나 추후에 진행할 것들은 // TODO : ~~ 로 해놓으시면 ide 에서 따로 검색되어서 편리합니다~
| public void start() { | ||
| // inputPlayers , inputExecutionResults로 쪼개야 하는지는 조금 더 고민 | ||
| Players players = new Players(); | ||
| players.makePlayers(inputView.inputNames()); |
| Players players = new Players(); | ||
| players.makePlayers(inputView.inputNames()); | ||
|
|
||
| ExecutionResults executionResults = new ExecutionResults(); |
There was a problem hiding this comment.
GameResultsDTO 는 어떨까요? 이 부분도 생성자에서 생성하면 안될지 의견이 궁금하네요
src/main/java/src/model/Ladder.java
Outdated
| } | ||
|
|
||
| public StringBuilder blueprintToLadderShape() { | ||
| StringBuilder sb = new StringBuilder(); |
| public class Referee { | ||
| private static final int IS_LADDER_BRIDGE_TRUE = 1; | ||
|
|
||
| private ArrayList<Integer> resultIndex = new ArrayList<>(); |
There was a problem hiding this comment.
이펙티브 자바 item 64 : 객체는 인터페이스를 사용해 참조하라
를 참고해보시면 좋을 것 같습니다
| class ExecutionResultsTest { | ||
|
|
||
| @Test | ||
| @DisplayName("실행 결과 입력 받았을 때 올바르게 split하여 저장하는지 테스트") |
There was a problem hiding this comment.
~할 때 ~한다 로 테스트의 arrange act assert 를 요약해주시면 좋을 것 같습니다
| ExecutionResults executionResults = new ExecutionResults(); | ||
| executionResults.makeExecutionResults(inputResults); | ||
|
|
||
| Assertions.assertThat(executionResults.getExecutionsResults().get(0).getResult()).isEqualTo("꽝"); |
| private Ladder ladder; | ||
| private int height = 5; | ||
| private int numberOfPlayers = 4; | ||
| private final int numberOfBridge = numberOfPlayers - 1; |
There was a problem hiding this comment.
이런 독립적인 데이터들은 활용하는 test 메서드에 적으시면 좋을 것 같습니다.
[사다리 게임 1주차]
진영 : 코드를 구현하다보니, 생각대로 로직이 구현되지 않아서 일단 돌아가게끔 만들어 놓고 리팩토링을 하자는 방향으로 진행하게 되었습니다. 특히 사다리 결과 매칭 로직에서 애를 먹었는데, 요구사항에서 이중 for문을 허용하지 않음에도 불구하고, 이중 for문으로 로직을 작성하게 되었습니다. 결국 하나의 for문으로 해결하는 방법을 알아내긴 했지만 시간이 많이 소요되어 리팩토링과 객체지향적 관점에서 코드를 생각하지 못한 점이 못내 아쉬웠습니다. 특히 어려움을 겪은 부분은 객체를 설계를 제대로 하지 않고 구현에 들어갔기 때문에 구현부에서 기준과 생각이 흔들리게 되는 점이었습니다. 기존 코드를 바탕으로 1주일 더 주어진 시간 동안 설계에 대한 고민과 여러가지 좋은 코드를 위해 활용할 수 있는 기법들을 학습하여 녹여내는 것을 목표로 삼아 열심히 해보겠습니다.
상엽 : 이번 미션을 진행하면서 가장 어려움을 느꼈던 부분은 역시나 기능에 따라서 클래스를 분리하는 부분이었다. 지난 자동차 경주 미션에서는 미션 자체의 기능 요구사항의 난이도가 높지 않았기에, 어느정도 기능 분리와 테스트코드 작성이 순조롭게 되었다. 그러나 이번 사다리 미션은 더 많은 기능이 요구되었고, 그에 따라서 기능 분리가 더 세분화 되어야 했다. 자동차 게임 미션을 통해 클래스를 나누고테스트코드를 짜고 예외처리를 하는 등 설계에 대해서 여러가지를 경험해 보았지만, 아직까지는 설계에 있어서 많이 부족하다는 느낌을 받았다. 또한 페어프로그래밍을 함에 있어서 나의 생각을 페어 동료에게 전달함에 있어서 어려움이 있었다. 이 또한 나 자신이 생각한 설계와 로직에 대해서 제대로 이해하지 못했고, 확신이 없었기 때문이라고 생각해서 계속해서 공부해서 보완해야할 부분이라고 생각했다. 모든 기능 요구사항은 구현에 성공했으나, 본래 미션의 목적인 테스트코드 작성과 클래스 분리, 예외처리 외 여러 조건들을 지키지 못해서 큰 아쉬움이 남았다.
[사다리 게임 2주차]
페어프로그래밍 회고 [Ladder Mission]
진영 : 저번 주와 이번 주는 사다리 게임 미션을 페어프로그램을 통해 진행하였다. 첫 주에 매칭된 페어와 구현을 하고 그 다음 주가 되서는 기존 구현했던 페어가 다른 팀의 페어와 바뀌어 페어프로그래밍을 진행하였다. 나는 내가 구현한 코드를 그대로 사용했지만, 바뀌게된 페어분은 아예 새로운 코드를 이해하느라 힘들었을 것 같다.
첫 주차의 페어프로그래밍은 시간에 쫓기어 우선 구현을 중점으로 진행을 하였다. 의외로 까다로운 비지니스 로직과 주어진 제한 조건을 지키기위해 시간이 많이 소요되었다. 사실 간단하다면 간단한 알고리즘이었지만, 디버깅에 시간을 꽤 들일 정도로 쉽게 구현되지 않았던 점이 시간을 많이 할애하게 된 원인인 것 같다. 일정이 서로 어긋난 날도 있어서, 기한을 맞추는 것이 꽤 힘들었다. 저번 주 페어분께 죄송스러운 마음이다.
이번 주는 완전하지 않았던 코드를 리팩토링 함과 동시에 제약 조건에 맞게끔 코드를 수정하는 과정을 거쳤다. 설계나 전반적인 클래스들의 구조를 어느 정도 갖추고 시작한 것이 아니라 바꿀 곳이 많았다. 페어분께서 잘 리딩 해주셔서 수월하게 리팩토링을 할 수 있었다. 특히 Dto나 원시값 포장에 대하여 집중할 수 있었는데 dto나 원시값 포장을 왜 해야하는 지에 대해서 어렴풋이 알고 있었을 뿐 정확히 알지 못했고 어떻게 해야하는 지 몰랐었다. 다행히도 페어분께서 알기 쉽게 내가 이해할 때 까지 몇번이고 설명해주셨다. 이젠 나도 dto 포장을 할 수 있게 되었다. 42서울을 하면서 익숙해진 코드 설명하기 과정도 재밌게 진행할 수 있었는데, 이해력이 좋은 페어분이 설명을 찰떡 같이 알아들어 주셔서 내심 신났다. 여러모로 많은 도움을 받고 얻어가는 것이 많았던 사다리 게임 미션이었다.
동건 : 항상 기능 요구 사항을 보고, 처음부터 설계하는 연습을 해왔었는데, 다른 동료가 개발하고 있는 와중에 참여해서 개발해본 경험은 처음이었다. 이번에 사다리 게임 같은 경우에는 사다리 만드는 알고리즘, 참여자를 움직이는 알고리즘이 중요했기에 설계 구조나 알고리즘이 새로웠다.
진영이형이 너무 친절하게 설명을 해주셔서 금방 코드에 이해하고 적응할 수 있었다. 그리고 진영이형이 저의 생각에 대해 먼저 물어봐주시고, 편하게 의견을 말하게 분위기를 만들어주어서 편하게 의견을 말하고 개발할 수 있었다.
하지만, 실무에서 프로젝트를 진행하고 있는 팀에 투입된다면, 어느 영역까지 나의 의견을 말할 수 있는가에 대한 궁금증이 생겼다. 물론 당연히, 팀의 특성에 따라 많이 달라지겠지만 앞으로 개발할 부분에 대해서만 참여해야 하는지, 이미 개발된 부분에 대해서도 참여해야 되는지에 대한 궁금증이 생겼다. 왜냐하면, 이미 개발에 참여했던 동료들에게 무례한 행동이라는 생각이 드는 것 같다.
나와 성혁이가 페어프로그래밍을 했을 때는 알고리즘 보다는 클래스 구조나, 설계에 대해 더 집중을 했다. 하지만 진영이형과 상엽이는 알고리즘에 더 집중을 했던 것 같다. 더 이해하기 쉬웠고 간결했고 효율적으로 느껴졌다. 클래스도 많이 줄어들었고 코드도 더 읽기 쉬워졌다. 다른 접근 방법에 대해 배울 수 있어서 뜻깊었다. 그리고 하나하나 부족했던 점들에 대해 리팩토링하면서 개선해 나가는 재미도 있었다.