본문 바로가기
우테코/프리코스

[우테코 5기 프리코스] 2주차 돌아보기

by dev_kong 2022. 11. 8.
728x90
728x90

0. 목차

1. 개요

2. 회고

3. 가장 많이 고민한 부분

4. 정리

1. 개요

어제(11월 7일 월요일) 프리코스 2주차 과제를 제출했다.
지식이 부족해서 일까. 더이상 어딜 고쳐야 될질 모르겠다.
절대 완벽하다는 소리가 아님;;


그.. 뭐랄까.
만약에 내가 건축가라면 좀 잘못지어진 건축물을 보고
'스읍..... 이거이거 건축 할줄 모르네'
라고 하겠지만
일반인들은 '헤헿 건축물 헤헿' 하고 말겠지.
지금 내가 그렇다.
'헤헿 야구게임 헤헿' 하고 있다.

헤헿 야구게임 헤헿

회고록이나 쓰고 자바 공부나 해야겠다.

 

2. 회고

2주차 미션은 야구게임 이었다.
미션을 받고 든 생각은 '역시나.. 근데 왜?' 였다.


우테코 관심있고, 진심인 사람들은 아마 전기수 전전기수 프리코스 문제들 한번씩은 검색해서 풀어봤을거라 생각하는데,
이전 기수 프리코스 첫주차 문제는 다 야구게임이었다.
그래서 어느정도 야구게임이 나오지 않을까 하는 생각은 있었지만,
왜 매 기수 마다 같은 과제를 주는가에 대한 의문은 남아있다.

 

우선 이번 과제에서 내가 중점적으로 삼았던 부분은 MVC 패턴TDD 이다.

 

2-1. TDD

TDD는 과제를 알려주는 메일에서도 하라고 대놓고 나와있었다.


2주 차 미션에서는 1주 차에서 학습한 것에 더해 함수를 분리하고, 각 함수별로 테스트를 작성하는 것에 익숙해지는 것을 목표로 하고 있어요


사실 이제껏 테스트 코드를 작성해본적도 없고, TDD라는것의 개념조차 잘모르는 상황이었기 때문에
해당 미션을 받았을 때 조금 막막한 기분이 들긴했었다.

 

우선 TDD가 뭔지 자세히 알아보고 직접 적용을 해보았다.
https://kong-dev.tistory.com/185

 

[Java] TDD 톺아보기

수정과 지적 환영합니다. 막 대해 주세요. 0. 목차 1. 개요 2. TDD란? 3. 테스트 코드 작성 4. 정리 1. 개요 우테코 2주차 미션에 JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을

kong-dev.tistory.com

 

작업순서는 이러했다.

  1. test code 작성 (method가 있다는 가정하에 작성하였음)
  2. method 작성
  3. test 성공
  4. 리팩토링

위의 포스팅 내용에서 공부한 내용과 최대한 부합하도록 작업하였고,
하는 과정에서 온탕과 냉탕을 왔다갔다하는 기분을 느끼게 해줬다.

 

테스트 코드를 작성할 때는 우선 귀찮다.


당장 빨리 기능 구현을 해야할 것 같은데 테스트코드를 만들고있으니
결국 코드량이 늘어나고 작업량이 늘어나고 생산성이 떨어지는 거 아닌가 싶은 생각도 들었다.

근데 TDD의 진가는 디버깅할때 드러난다.
기능이 내가 생각한 대로 짜-잔하고 나오면 정말 좋겠지만,

짜-잔


대부분 그렇지 않다.

이전 같았으면 하나하나 출력해보면서 '..어디가 잘못된건데..뭔데..나한테 왜그래..' 라고 중얼거리겠지만
브레이크 포인트 찍으면서 테스트 돌리면서 디버깅하니까 진짜 편하다..!

 

편한걸 더 편하게 쓰기위한 공부도 조금 했었다.
https://kong-dev.tistory.com/186

 

[Java] JUnit ParameterizedTest input 여러개 테스트 돌리기

0. 목차 1. 개요 2. 여러개 테스트 한큐에 돌리기(ParamterizedTest) 3. 그외에도 이것저것 1. 개요 프리코스 2주차 2일째. 고난과 역경의 TDD 하다가 input 여러개 넣고 한큐에 테스트 돌리는 방법 찾다가

kong-dev.tistory.com

공부한 내용을 토대로 다음 주차에서는 더 잘해봐야지..!

 

2-2. MVC 패턴

그다음으로 중점적으로 생각한 부분은 MVC 패턴에 관한 내용이다.
코드의 유지보수성을 높인다가 MVC 패턴의 궁극적인 목적이지만,
그외에도 설계의 구조를 정형화 하여, 이러한 부분에 대해 고민할 필요가 없어지고, 이는 곧 생산성의 향상으로 이어질 수 있다고 생각한다.

 

나는 후자의 목적에 조금 더 집중해봤다.
결국 내가 코드 짜는 방식을 정형화 하기 위해 사용했다는 뜻이다.

 

실제로 작업을 하면서 코드가 각각의 목적에 맞게 작성된 것이 코드를 수정 또는 리팩토링 할때 유용하다는 것을 깨닫게 되었다.
물론 아직 많은 연습이 필요할것 같다.

 

그래도 궁금해했던 부분을 이번 과제를 하며 해결 할 수 있었다.
domainservice에 관한 내용이었는데, 아래의 포스팅에 정리를 했었다.

 

https://kong-dev.tistory.com/187

 

[Java] MVC 패턴 그리고 domain, service

0. 목차 1. 개요 2. MVC 패턴 3. domain과 service 1. 개요 우테코지원 해야겠다 마음먹고, 이전기수 프리코스 내용 검색해서 찾아본적이 있었다. 이전기수 분들의 블로그 글들에서 공통적으로 보이던 것

kong-dev.tistory.com

또한 추가적으로 Java문법에 대해서도 부족함을 다시 깨닫고 많이 공부를 할수 있는 시간이었다.

 

3. 가장 많이 고민한 부분

마지막으로 이번 과제의 코드를 작성하면서 가장 많이 고민했던 부분에 대해 작성해보려 한다.

public class Game {
    private List<Integer> answer = new ArrayList<>();

    public Game(List<Integer> randomNumberList) {
        this.answer = randomNumberList;
    }

    public Map<String, Integer> getResult(String userAnswer) {
        Map<String,Integer> resultMap = new HashMap<>() {{
            put("ball", 0);
            put("strike", 0);
        }};

        List<Integer> answerIntegerList = Converter.toIntegerList(userAnswer);
        for (int index = 0; index < answerIntegerList.size(); index++) {
            Integer currentInteger = answerIntegerList.get(index);
            if (Objects.equals(answer.get(index), currentInteger)) {
                resultMap.put("strike",resultMap.get("strike") + 1);
                continue;
            }

            if (answer.contains(currentInteger)) {
                resultMap.put("ball",resultMap.get("ball") + 1);
            }
        }
        return resultMap;
    }
}

내가 만든 Game class 이다.

꼴랑 하나있는 저 method가 고민이었다.

고민했던 부분은 두가지였는데,

  1. getResult method가 Game class 안에 있는게 맞는 걸까?
    1. Result class를 따로 만들어야 하나..
  2. getResult method의 리팩토링을 어떻게 진행 해야 할까?
    1. 일단 변수명 마음에 안들어…
    2. if 문 조건절이 눈에 확 들어오는 느낌이 안들어..
    3. 클린코드에 따르면 loop 안에서 continue || break 쓰지 말라던데…
    4. indent2 까지 허용이긴 한데 그래도 1로 만들고 싶은데..

1번에 대한 고민만 계속하면서 시간만 버리는 기분이라

당장 할수 있는 2번부터 시작했다.

 

2-1. 변수명 변경

변수명을 조금씩 수정했다.

 

public Map<String, Integer> getResult(String userInput) {
    Map<String,Integer> resultMap = new HashMap<>() {{
        put("ball", 0);
        put("strike", 0);
    }};

    List<Integer> userAnswer = Converter.toIntegerList(userInput);
    for (int index = 0; index < userAnswer.size(); index++) {
        Integer currentAnswer = answer.get(index);
        Integer currentUserAnswer = userAnswer.get(index);

        if (Objects.equals(currentAnswer, currentUserAnswer)) {
            resultMap.put("strike",resultMap.get("strike") + 1);
            continue;
        }

        if (answer.contains(currentUserAnswer)) {
            resultMap.put("ball",resultMap.get("ball") + 1);
        }
    }
    return resultMap;
}

 

2-b & 2-c. continue 지우기, if 조건절 method로 따로 빼기.

처음으로 든 생각은 “b 와 c를 하나로 묶어서 해결 할 수 있을 것 같다” 였다 .

if 조건절에 조건을 추가하면 continue 없이 코드를 짤 수 있었다.

 

for (int index = 0; index < userAnswer.size(); index++) {
        Integer currentAnswer = answer.get(index);
    Integer currentUserAnswer = userAnswer.get(index);

    if (Objects.equals(currentAnswer, currentUserAnswer)) {
        resultMap.put("strike",resultMap.get("strike") + 1);
    }

    if (answer.contains(currentUserAnswer)
            && !Objects.equals(currentAnswer,currentUserAnswer)) {
        resultMap.put("ball",resultMap.get("ball") + 1);
    }
}

 

가독성 사망선고…

if의 조건절을 전부 boolean을 return 하는 method로 빼버리자.

 

public Map<String, Integer> getResult(String userInput) {
    Map<String,Integer> resultMap = new HashMap<>() {{
        put("ball", 0);
        put("strike", 0);
    }};

    List<Integer> userAnswer = Converter.toIntegerList(userInput);
    for (int index = 0; index < userAnswer.size(); index++) {
        Integer currentAnswer = answer.get(index);
        Integer currentUserAnswer = userAnswer.get(index);

        if (isStrike(currentAnswer,currentUserAnswer)) {
            resultMap.put("strike",resultMap.get("strike") + 1);
        }

        if (isBall(currentAnswer, currentUserAnswer)) {
            resultMap.put("ball",resultMap.get("ball") + 1);
        }
    }
    return resultMap;
}

 

조금이나마 깔끔해진것 같다.

 

 

2-d. indent

이번엔 if문을 묶어서 하나의 method로 빼버리자.

그러면 getResult의 indent를 1로 유지 할수 있다.

 

public Map<String, Integer> getResult(String userInput) {
    Map<String, Integer> resultMap = new HashMap<>() {{
        put("ball", 0);
        put("strike", 0);
    }};

    List<Integer> userAnswer = Converter.toIntegerList(userInput);
    for (int index = 0; index < userAnswer.size(); index++) {
        Integer currentAnswer = answer.get(index);
        Integer currentUserAnswer = userAnswer.get(index);

        countScore(resultMap, currentAnswer, currentUserAnswer);
    }
    return resultMap;
}

 

점점 맘에 들기 시작했다.

countScore 인자값 3개 마음에 안든다…. resultMap을 전역으로 빼자.

 

public Map<String, Integer> getResult(String userInput) {
        List<Integer> userAnswer = Converter.toIntegerList(userInput);

        for (int index = 0; index < userAnswer.size(); index++) {
            Integer currentAnswer = answer.get(index);
            Integer currentUserAnswer = userAnswer.get(index);

            countScore(currentAnswer, currentUserAnswer);
        }
        return resultMap;
}

 

resultMap을 전역으로 뺀 대신에

getResult 호출 전에, resultMap을 초기화 해주는 함수를 대신에 추가했다.

 

여기까지 수정하고 나니 든 생각은
지금 내가 작성한 class는 Game class가 아닌 Result class다. 였다.

 

이번 미션의 과제는 여기까지의 기능만 돌아가면 되는 거지만,
이 야구게임을 실제로 서비스를한다고 가정하고 생각을 해봤다.

 

Game의 요소에는 Result를 포함해 User도 있을 수 있고, Ranking도 있을 수 있다.
이외에도 다른 요소들이 추가 될수 있고, 이 모든걸 포함하여 하나의 Game이 된다고 생각했다.

 

그래서 현재 만들어진 Game class를 모두 Result class로 옮기고,
Game class 에서는 userInput을 param으로 받아 Result의 getResult를 호출하는 방식으로 코드를 전면 수정했다.

 

수정된 코드는 아래 깃헙에서 확인할 수 있다..
https://github.com/green-kong/java-baseball/tree/green-kong

 

GitHub - green-kong/java-baseball: 숫자 야구 게임 미션을 진행하는 저장소

숫자 야구 게임 미션을 진행하는 저장소. Contribute to green-kong/java-baseball development by creating an account on GitHub.

github.com

 

4. 정리

쓰다보니 또 주저리주저리가 돼버렸는데,

이번 과제를하면서 새로운 것들을 접해보며 성장할 수 있었다.

 

처음에는 야구게임 미션을 받고 쉽게만 생각했다.

야구게임과 비슷한 wordle 도 만들어 본적이 있어서 로직적으로 어렵진 않았는데,

클린코드나, MVC 패턴, 테스트 코드 작성 같은 완전히 새로운 것들을 시도해 볼 수있는 좋은 기회였다.

 

우테코 지원하기 전에 많은 고민들이 있었는데, 지원하게 돼서 참 다행이다.

멋진 말을 쓰고 싶은데 머릿속이 백지라서 못하겠다...

 

 

728x90
728x90

댓글