출석 미션은 최종 코딩테스트 때 나왔던 미션이었다.
선배들의 글에 따르면 보통 2주 차는 사다리 타기 미션을 하는 것처럼 보였는데 이번엔 출석 미션이라 의아하면서도 새로웠다.
사실 작년에 네이버 부스트캠프 베이직 과정에서 자바스크립트로 비슷하게 사다리 게임 만들기를 했었는데, 익숙하지 않은 자바스크립트여서 그런지 정말 어려웠었다.
그래서 자바로 만드는 사다리타기는 어떨까 기대를 하기도 했었는데 살짝 아쉽긴 했다!
(미래의 듀이야 아쉬우면 시간 날 때 사다리 타기 미션 따로 해보던가!🫠)
이번 미션의 주제는 TDD!
프리코스 때부터 ‘우테코에서는 TDD를 강조한다. TDD로 프리코스를 연습해 보면 좋다.’라는 말들을 많이 들었다.
그렇지만 프리코스 직전 TDD에 대한 대략적인 감을 잡기 위해 한별언니와 했던 스터디에서도 TDD의 장점을 직접 느끼지는 못했었다.
그래서 프리코스 때는 TDD를 도입하지는 않았었고, 도메인에 대한 테스트를 최대한 작성하는 방향으로 테스트에 대한 감만 익혔었다.
하지만 이번에는 처음부터 페어와 함께하는 미션이고, TDD를 강제로 시도해보기에 좋은 환경이었다.
출석 미션의 페어는 포포였고, 처음에는 낯을 좀 가리나 싶었는데 생각보다 재미있는 구석이 많은 크루였다.
그래서 미션하는 내내 웃었던 기억이 많다.
포포는 Lambda와 Stream을 자유자재로 사용할 수 있는 크루였다. 나는 람다 스트림에 익숙하지 않아서 한창 연습을 하고 있는 단계인데, 리팩터링 과정에서 for문을 스트림으로 변환하는 모습을 보고 어떤 흐름으로 변환하는지 잘 배울 수 있었다.

그래서 이렇게 피드백을 남겼는데, 오히려 포포는 내가 index를 잘 활용하지 못하는 편이라 그림으로 그려가며 이해했던 부분을 좋게 봐주었는지 아래와 같은 피드백을 주었다.

내가 부족하다고 느낀 점을 좋게 봐주는 페어라니..? 신기하고 기분이 좋기도 했다🥹
아무래도 최종 코딩 테스트 때 한 번 해봤던 미션이어서 그런지 초반엔 수월하게 진행이 됐다. 나는 최종 코테 때 출석 기능 정도만 구현을 하고 5개의 테스트 중 4개만 통과했었기 때문에 도메인 구현이 진행될수록 어려움을 느꼈다.
그런데 듣자하니 포포는 최종 코테 때 모든 테스트 케이스를 만족했고, 구현도 어느 정도 다 했던 것 같아서 후반부로 갈수록 포포가 미션을 잘 이끌어주었다.
이번 미션도 역시 최종 코테 때보다 미션에 대한 요구사항이 불친절했다.
출력 요구사항이 올바르지 않다거나, 파일 입출력을 해야 하는데 csv 파일을 우리가 만들어야 한다거나..!
그렇지만 이 정도는 포포와 함께 정하고 할 수 있는 부분이었다.
TDD와 DDD
나는 이번 미션을 페어와 함께 TDD로 진행하면서 TDD는 DDD를 위해, 더 나은 설계를 위해 하는 것이라고 말할 수 있게 되었다.
포포와 함께 할 땐 '출석' 미션이기 때문에 익숙한 '출석' 도메인에 대한 TDD를 먼저 진행하고, 이후에 필요한 도메인이 생기면 추가로 TDD를 하는 방식으로 진행했다.
이때 했던 게 Out -> In 방식이라는 것을 나중에 알게 됐다.
다만 이렇게 분리해 나가면 뭔가 한 가지 도메인에 대한 테스트와 구현이 끝나기 전에 다른 더 작은 도메인이 생기고, 또 다른 더 작은 도메인이 생기고 하다 보니 일만 벌여 놓는 것 같아 불편한 느낌을 지울 수 없었다.

그래서 1단계 PR에서 도메인 분리를 어떻게 해야 할 지, 어디까지 해야 할지 리뷰어인 샐리에게 질문을 하게 됐다.
확실히 코드를 작성하면서 느낀 점들이어서 그런가 글로 작성하기가 한결 수월했다.

이런 내 질문에 샐리도 우선 돌아가도록 만들고, 하나의 케이스씩 테스트로 작성하고 분리해 가는 과정으로 진행했을 것 같다는 답변을 주었다.
TDD를 하는 과정이 도메인을 알아가는 과정이고, 설계를 하는 과정이긴 하지만 '우선 돌아가는 것을 만든다'는 것이 더 중요한 점이라고 느꼈다.
1단계 미션이 끝나고 있었던 네오의 TDD 수업에서 Out -> In 방식과 In -> Out 방식을 알게 됐다.
Out -> In 방식은 도메인 지식이 없거나 요구사항을 객체로 도출할 수 없는 경우에 사용하는 TDD 방식이고,
In -> Out 방식은 도메인 지식이 있거나 요구사항을 객체로 도출할 수 있는 경우에 사용하는 TDD 방식이다.
엄밀히 보자면 나는 출석 미션을 한 번 구현해 본 상황이었기 때문에 출석에 대한 도메인 지식이 있었던 것이다. 그런데 이번 미션을 Out -> In 방식으로 진행했었고, 더 작은 도메인을 이미 알고 있는 상황이었기 때문에 TDD 과정이 불편하게 느껴졌던 것 같다.
그래서 2단계에서는 좀 더 세세한 도메인 로직부터 테스트 하는 방법을 택하기로 했다.
이번 미션을 진행하면서 TDD가 DDD를 위해, 그리고 더 나은 설계를 위한 것임을 정확하게 말할 수 있게 된 것은 이런 고민을 하는 과정에서 깨닫게 된 것 같다.
작은 단위에서부터 TDD를 진행하고, 이 과정을 통해 도메인에 대한 이해도가 더 높아지고, 더 작은 도메인을 알아내고, 절차가 진행됨에 따라 더 좋은 설계가 나온다고 느꼈다.
그리고 TDD의 든든함은 리팩터링을 진행하면서 더 크게 느껴졌다.
도메인에 대한 이해를 바탕으로 작성된 테스트들이었기 때문에, 리팩터링을 하면서 테스트가 깨지면 도메인에 대해 이해가 잘못 된 것인가 다시 한 번 생각해볼 수 있었고, 빠르게 문제점을 찾아 대응할 수 있었다.
controller의 역할
로또 미션 때부터 고민했던 controller의 역할에 대해 이번 미션에서 확실히 정의할 수 있었다.
물론 아직까지는 콘솔 프로그램이기 때문에 내가 정의한 controller의 역할과 웹 MVC의 컨트롤러의 역할은 다를 수 있다.
하지만 웹 MVC에서의 역할은 그 때 가서 다시 정의하면 되는 것이라고 생각한다. 요구사항도, 내가 정의한 모든 것들도 언제든 변할 수 있고, 유연함을 가지면 된다!
우선 객체의 책임에 집중하기 위해서는 domain에서는 view를 위한 코드가 존재하지 않아야 하고, view에서는 domain이 존재해도 된다고 생각했다.
그래서 inputView에서는 controller에게 원시값을 넘기고, controller에서 domain이 필요한 값들을 객체로 생성하여 domain에게 전달해 주도록 했고, 반대로 outputView에서는 controller로부터 domain을 넘겨받고 있었다.

이런 내 코드에서 샐리는 view에서 도메인에 대해 모든 정보를 알고 있는데, view와 domain을 분리해 보면 어떨지 제안해 주었다.
나는 MVC에 대해 domain에서는 view를 몰라야 하지만, view는 domain을 알아도 된다고 생각했고, 분리를 위해 domain에서 다른 객체를 생성해서 view에게 넘겨줘야 하는 것이냐고 되물었더니 샐리는 controller의 역할을 뭐라고 생각하냐고 역질문을 해주었다.
inputView에서 받은 원시값을 controller에서 가공하여 domain으로 던져줘 놓고, outputView에게 넘겨줄 때 controller에서 가공할 생각을 못했던 거다.
샐리의 역질문에 깨달음을 얻었고, 미션에서 controller의 역할에 대해 확실히 정의할 수 있게 되었다.
다만 여전히 객체의 책임에 집중하기 위해서 구현 초반에는 outputView에 그대로 domain을 넘겨주는 방식을 택하고 있다.
controller의 책임만 명확히 알고 있다면, 리팩터링 과정에서 outputView에게 domain을 다른 객체로 변경하여 넘겨주는 방식은 쉽게 수정할 수 있기 때문이다.
이번 출석 미션을 통해 가장 크게 배우고 깨달은 점은 이렇게 딱 두 가지로 볼 수 있겠지만,
이 외에도 소소하게 배우고 깨달은 점들이 너무 많다.
샐리의 리뷰와 질문을 통해 혼자 생각하고 고민하고, 그 결론을 글로 작성하고, 코드로 표현해 내는 과정 속에서 배운 점이 많았다.
두 번째 미션부터 이렇게 배우고 깨달은 점이 많았는데, 앞으로 얼마나 더 깨닫고 성장할 수 있을지!!
아무래도 리뷰의 과정에서 깨달은 점이 많다 보니, 이번에는 PR 주소를 첨부해야겠다.
1단계 PR: https://github.com/woowacourse/java-attendance/pull/36
[1단계 - 출석 구현] 듀이(이주희) 미션 제출합니다. by ljhee92 · Pull Request #36 · woowacourse/java-attendanc
안녕하세요 샐리, 7기 BE 크루 듀이입니다. 먼저 소중한 시간 들여 리뷰해주셔서 감사합니다! 1단계는 페어와 함께 ‘돌아가는 쓰레기’라도 만드는 것을 최우선 목표로 했기 때문에 리팩토링을
github.com
2단계 PR: https://github.com/woowacourse/java-attendance/pull/129
[2단계 - 출석 다시 구현하기] 듀이(이주희) 미션 제출합니다. by ljhee92 · Pull Request #129 · woowacourse/
체크 리스트 미션의 필수 요구사항을 모두 구현했나요? Gradle test를 실행했을 때, 모든 테스트가 정상적으로 통과했나요? 애플리케이션이 정상적으로 실행되나요? 프롤로그에 셀프 체크를 작성
github.com
'study > 우아한테크코스' 카테고리의 다른 글
| 우아한테크코스 7기 백엔드 레벨1 장기 미션 회고 (0) | 2025.04.17 |
|---|---|
| 우아한테크코스 7기 백엔드 레벨1 블랙잭 미션 회고 (0) | 2025.04.08 |
| 우아한테크코스 7기 백엔드 레벨1 로또 미션 회고 (1) | 2025.03.17 |
| 우아한테크코스 7기 백엔드 최종 합격 회고 (10) | 2024.12.29 |
| 우아한테크코스 7기 1차 합격 + 최종 코딩 테스트 후기 및 회고 (7) | 2024.12.16 |