후기🔥/회고록

NextStep TDD, Clean Code with Java 수료 후기

안주형 2023. 6. 5. 00:23

서론

4.3~6.1 약 8.5주간 NextStep에서 진행하는 TDD, Clean Code With Java 16기 과정에 참가했다. 참가하게 된 계기는 많은데, 정리해 보면 다음으로 요약할 수 있다.

  • 실제 카xx, 11xx등의 기업에서 넥스트스탭의 교육 과정을 통해 신입 온보딩을 진행하고 있고, 우테코나 우테캠의 일부 과정이랑도 비슷해 검증된 강의 퀄리티라고 생각했다.
  • 이펙티브 자바, 클린코드, TDD와 같이 책을 통해 혼자 이론만 익혔던 지식들을 실습을 통해 활용을 해 볼 수 있다.
  • 내가 아는 주변에 뛰어난 사람들은 공통적으로 넥스트스탭의 강의를 하나 이상은 수료했다.

과정 자체는 약 두 달간 진행되며 크게는 4개, 세부적으로는 17개의 자바 미션을 수행해야 한다. 미션을 수행하면 PR을 올리고, 멘토들의 리뷰를 통해 merge가 되는 식으로 진행이 되는데, 80만 원이라는 작지 않은 금액의 과정임에도 불구하고 전 과정을 수료하는 수료율은 전체 인원의 10~20%가 채 되지 않는다고 한다. 실제로 이번 기수에서도 120~130명 정도가 참가했지만, 6/1일까지 전 과정을 수료한 인원은 10명 남짓이었던 것 같다.
 

미션

내가 진행한 모든 미션의 PR과 진행하면서 내가 배웠던 점을 정리하면 다음과 같다.

자동차 경주 - 단위테스트

패키지별로 책임을 분리하고, JUnit의 사용법을 익혀서 단위테스트를 하는 법에 대해 익혔다. 특히나 이번 단계의 원칙이 있었는데, 아래와 같은 규칙을 통해서 메서드를 분리해 메서드가 한 가지 작업만 담당하도록 구현하는 연습을 하는 것이 강의 목표였다.

  1. 한 메서드에 오직 한 단계의 들여 쓰기만 한다.
  2. else 예약어를 사용하지 않는다.
  3. 메서드의 라인 수가 15라인을 넘어가지 않아야 한다.

그리고 자동차 경주 미션을 통해 메서드 분리뿐만 아니라 일급컬렉션과 전략패턴의 활용에 대해서 익힐 수 있었다.

로또 - TDD

로또미션의 2,3,4단계는 이전의 자동차 경주와 비슷하다는 느낌이 들었고, 새로운 걸 익히기보다는 이전 단계에서 학습한 메서드 분리와 일급컬렉션, 전략패턴, 단위테스트에 대한 이해를 한번 더 실습을 해봄으로써  잘 갈무리시키는 걸 목표로 했다.

로또 미션에서 가장 기억에 남는 미션은 "1단계 - 문자열 계산기"다. 요구사항은 단순히 사용자가 입력한 문자열 값에 따라 사칙 연산을 수행할 수 있는 계산기를 구현하는 것인데, 이게 들여 쓰기를 한 번만 해야 하고, else를 사용하면 안 된다는 조건 때문에(당연히 switch도 안되고, 그렇다고 if 떡칠도 안된다.) 조금 새로운 접근을 통해 구현해야 한다.

package domain;

import java.util.Arrays;
import java.util.function.BiFunction;

public enum Operator {
    PLUS("+", (num1, num2) -> Integer.valueOf(num1 + num2)),
    MINUS("-", (num1, num2) -> Integer.valueOf(num1 - num2)),
    MULTIPLY("*", (num1, num2) -> Integer.valueOf(num1 * num2)),
    DIVIDE("/", (num1, num2) -> Integer.valueOf(num1 / num2));

    private final String operator;
    private final BiFunction<Integer, Integer, Integer> calculator;

    Operator(String symbol, BiFunction<Integer, Integer, Integer> calculator) {
        this.operator = symbol;
        this.calculator = calculator;
    }

    public String getOperator() {
        return operator;
    }

    public static Integer calculator(String operator, Integer num1, Integer num2) {
        return getOperator(operator).calculator.apply(num1, num2);
    }

    private static Operator getOperator(String operator) {
        return Arrays.stream(values())
                .filter(o -> o.operator.equals(operator))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("사칙 연산 기호만 가능합니다."));
    }
}

이건 사칙연산을 구현한 내 코드이고, Enum과 함수형 인터페이스를 통해 구현했다.  BiFunction은 사내에서도 자주 보이는 코드들이라 익숙했는데, Enum은 스스로도 이렇게까지 활용할 수 있을 줄은 몰랐다. 구현하면서도 놀랐고, 앞으로도 꾸준히 활용할 수 있을 정도로 계속해서 학습해야 할 것 같다.

사다리타기 - FP, OOP

사다리타기의 미션을 통해서는 크게 아래의 세 가지를 학습을 하는 것이 목표였다.

  1. 크게 스트림, 람다를 통해 함수형 프로그래밍을 하는 경험
  2. In -> Out, Out -> In 방식으로 도메인 객체를 설계하는 경험
  3. 책임주도설계 기반으로 인터페이스를 활용해 프로그래밍을 하는 연습

그리고 이번 미션에 추가로 지켜야 할 객체지향 생활 체조 원칙은 다음과 같았다.

  • 디미터 법칙을 지킨다.
  • 모든 엔티티를 작게 유지한다.
  • 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
  • 게터/세터/프로퍼티를 쓰지 않는다.

나는 이 중에서 세 번째 "3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다." 이게 굉장히 어려웠다. 3개 이상이란 말은 두 개까지만 써야 한다는 말이었고, 미션을 진행하다 보면 딱 세 개까지만 쓰면 손쉽게 구현할 수 있을 것 같은데 두 개까지만 써야 한다는 조건 때문에 굉장히 구현하기 까다로운 부분이 있었다.

public class LadderResults {
    private final Map<Participant, LadderResult> ladderResults;

    public LadderResults(Map<Participant, LadderResult> ladderResults) {
        this.ladderResults = ladderResults;
    }

    public LadderResult getResultForParticipant(Participant participant) {
        return Optional.ofNullable(ladderResults.get(participant))
                .orElseThrow(() -> new IllegalArgumentException(participant.getName() + " 참가자가 존재하지 않습니다."));
    }

    public Map<Participant, LadderResult> getAllResults() {
        return ladderResults;
    }

}

당장에 코드만 봐서는 내가 말한 내용이 이해가 안 가겠지만, 최대한 클래스를 분리시키고, 일급컬렉션으로 묶고, 그걸 또 Map으로 묶는 방법을 통해 해결했다.
 

수강신청 - 레거시 코드 리팩터링

수강신청 미션은 이번 16기에 새롭게 추가된 미션이었다. 처음부터 코드를 작성하는 것이 아니라, 실제 현업에서 마주칠 법한 레거시 코드가 주어졌고, 이를 지금까지 학습한 TDD, OOP, 클린코드 기반으로 점진적으로 리팩터링 하는 것이 미션의 목표였다.

첫 미션이다 보니, 참고할 레퍼도 없었고 그렇다 보니 난이도가 급격하게 높았다고 생각한다. 특히나 미션의 코드는 jdbcTemplate였기 때문에 JPA기반의 도메인 설계와 비즈니스 로직을 작성해 오는데 익숙했던 나는 코드를 작성하면서도 코드에 정답은 없다지만 이게 과연 올바른 방식일까?라는 의문점이 계속 들었다. 그리고 실제로도 가장 많은 리뷰 핑퐁이 오갔던 미션이었다.

마지막 미션을 통해서 그동안 익혔던 TDD, OOP, 클린코드를 통해 레거시 코드를 스트랭글러 패턴으로 리팩터링 하는 방법을 학습할 수 있었다.
 

정리

회사 업무와 현재 진행하고 있는 동아리인 디프만까지 같이 병행해야 했기에 미션 기간인 두 달 동안 매우 바쁘게 살았던 것 같다. 멘토들도 현직자이기에 하루에 한 번 PR 리뷰를 진행해 주었고, 그렇기에 하나의 PR에 2~3번의 리뷰가 오간다고 가정하면 사실상 거의 쉬는 날 없이 PR을 올리고, 수정하고 재 PR 하고 이런 방식으로 진행해야 수료할 수 있기 때문이다. 여하튼 뭐 밤잠을 줄여 두 달 동안 매일 6시간 미만으로 잠을 자며 여자저차 과정을 수료했다.

TDD, Clean Code with Java 과정을 통해 나의 코딩 스타일이 이전과는 확연하게 달라졌고, 매우 개선되었다고 생각한다. 그리고 배운 점을 토대로 코드작성과 다른 사람의 코드 리뷰를 더욱더 자신감 있게 할 수 있게 되었다고 생각한다. 혹시나 누군가 나에게 이 강의가 어떻냐고 물어본다면 1~3년 차의 개발자라면 한 번쯤은 꼭 수강해 보라고 권하고 싶다.