[우아한테크코스 6기] 레벨 2: 1주 차 회고

,

방학이 쏜살같이 지나갔고, 새로운 레벨이 시작되면서 함께할 조도 바뀌었다! 방학 동안에는 모자란 잠을 내리 자느라 시간이 다 간 듯… 브리네오조 MT도 다녀왔는데, 일정이 딱 시작하는 전 날에 끝나도록 돼 있어서 몸살을 좀 앓았다. 이 때문인지는 모르겠지만 감기 때문에 수목금 내리 고생했다 🥹

1레벨 때에는 자바와 객체지향에 대해 깊은 생각을 해 보았다면, 2레벨부터는 본격적인 웹 서버를 구축하기 위한 스프링 프레임워크를 활용하게 된다. 겪어보지 못했던 새로운 타입의 학습을 진행하게 돼서 즐겁게 지낸 한 주. 왜인지 모르겠지만 화요일부터 시작했음에도 불구하고 이번 주의 시간이 꽤나 느리게 가는 느낌이었다. 아파서 그런가 😭

☀️ 솔라조 반가워요

즐거웠던 브리조를 떠나고 새로운 데일리 조와 함께하게 됐다. 열 명의 크루들이 1레벨 때에는 말을 많이 섞어보지 않았던 사람들이라, 처음에는 어색함을 깨는 데 혼났다 ㅋㅋㅋ 잉크 초롱 마크 로빈 제제 애쉬 감자 리건 새양 반가워요 🙌🏻 첫 데일리에서는 여느 때와 다름없이 자기소개하는 시간을 가졌다. 적막한 공기가 감돌 때마다 참지 못했던 리건과 나는 매번 눈을 마주쳤다 👀

2레벨에 들어오면서 페어도 다른 조 사람들과 매칭된다는 걸 알았다. 1레벨 때에는 같은 조원 중에서도 연극을 같이 했던 다섯 명 안에서 놀았는데, 이번에 우물 밖(?)으로 나오게 되면서 다양한 사람들과 코드를 짜는 연습을 하게 되었다. 2레벨 조원들과 조금 더 가까워질 수 있는 시간이 줄어들어 아쉬운 마음이 컸다. 프로젝트를 시작하는 레벨 3부터는 본격적으로 팀원들과 함께 코드를 짤 거라, 1단계와 3단계를 잇는 단순한 징검다리가 아니기를 바란다 👋🏻

🫂 시작과 함께하는 미션

시작이 끝나기 무섭게 페어 프로그래밍 미션이 주어졌다. 페어가 모든 크루와 랜덤하게 매칭되는 광경을 강의실에서 목격했다. 이번 페어는 다온이었다! 얼굴도 서로 알고 잡담도 나눴던 크루라 코드 성격이나 컨벤션, 스프링에 대해서 많은 이야기를 주고받았다. 둘 다 스프링에 대한 경험이 조금은 있었어서 그런가, 굉장히 빠르게 완성했다.

어떻게 된 게 만난 지 네 시간만에 헤어져요…

코드를 작성하면서도 어떤 것을 써야 할 지, 다른 방법은 없는지 토론했지만 뭔가 지금 단계에서 이야기할 것은 아닌 토픽들이라 제쳐두고 구현에 집중했다. 특히나 처음에 주어진 컨트롤러는 일을 너무 많이 하고 있는 느낌이라 리팩터링을 해야 한다고 생각했지만, 이후에 계층화라는 부분이 있어 넘어가기로 했었지만…

🧽 네오는 잊어라, 레벨 1은 잊지 말라

레벨 1에서 뭘 했더라

수업을 담당하는 코치가 바뀌었다보니 자연스레 피드백을 진행하는 방향이나, 크루들과 지식을 나누어가는 방법이 달라지기 시작했다. 1레벨 때 우리를 이끌어주었던 네오를 잊지 말라는 이야기가 가장 먼저 나올 정도였다. 다만 이 이야기는 레벨 1을 잊으라는 게 아니었다… 컨트롤러에게서 들려오던 리팩터링의 신호는 레벨 2에서 신경쓸 일이 아니었다. “하나의 객체는 하나의 일만” 하는, 레벨 1에서 주욱 해왔던 내용이었다.

레벨 1이 사라졌네요

결국 내가 올렸던 PR의 리뷰에서도, 리뷰어와의 DM에서도 이런 이야기가 들려왔다. 스프링과 객체지향을 어떻게 조화롭게 작성할 수 있을까? 에 대한 고민을 꾸준히 해나가는 게 중요하겠다. 이후에는 다시 체스 때의 기억을 더듬어 Dao, 비즈니스 로직을 담당하는 객체를 만들어나가는 것으로 마무리했다.

🏝️ 개발 철학으로부터 결론 도출하기

레벨 1에서 얻어간 것이 뭐냐고 한다면 가장 먼저 추상화 수준에 대한 이야기할 것이다. 그만큼 나의 개발 철학에 한 획(?)을 그었던 주제였고, 이번 테코톡에서 이야기할 내용이기도 하다. 처음으로 나의 철학에 기반한 결론에 도달하게 된 고민 주제가 있었다. 스프링에서의 @Controller에서, @ResponseBody가 존재하는 경우 단순 객체를 넘겨도 될 텐데 왜 ResponseEntity<>로 감싸주어야 할까? 였다.

우선 ResponseEntity로 감싸면 가져갈 수 있는 이점이 여럿 있다. 헤더를 설정할 수 있고, 상태 코드도 개발자의 입장에서 조작할 수 있다. 어떤 객체가 들어가는지, Body로는 어떤 게 들어가는지 메서드를 보면 확실하게 알 수 있다. 다만 별다른 조치 없이 200 OK를 뱉어야 하는 경우에는 ResponseEntity가 필요없지 않을까? 그냥 void를 리턴하더라도 알아서 해 주는데?

처음에는 결정을 내릴 수 없어 리뷰어와 고민을 나눴다. 리뷰어는 Controller가 서블릿의 응답을 내려주는 듯한 느낌이 드니, 모두 감싸주는 게 좋다는 판단이 들었고 나도 동의했다. 어떻게 보면 설득당한 것일까? 다른 크루들과 주장을 나눠나갈 때에는 다시금 흔들릴 수밖에 없었다. 어차피 같은 역할을 해나가는 것이고, 스프링이 뒤에서 ‘알아서’ 해 준다면 감싸지 않고 그냥 태워보내면 되지 않을까? 🤔

결론부터 이야기하면, Controller가 가지고 있는 추상화 수준과 맞춰주기 위해 ResponseEntity로 감싸줘야 한다는 게 나의 의견이다. Controller는 사용자의 요청에 적절하게 응답을 해주는 높은 추상화 단계를 가지고 있다. 이러한 메서드에서 단순한 List를 반환하거나, void를 반환한다면, 읽는 사람에게 이질감을 줄 수 있다. 이질감에 그치지 않고, 코드를 읽어나가는 사람에게 Spring이 어떻게 처리하는지를 요구하게 되는 상황이 발생하기도 한다.

그렇다면 이를 어떻게 할 수 있을까? 요청에 대한 응답은 HTTP Response로 이루어질 것이고, 이를 추상화한 것이 ResponseEntity이다. ‘요청’이 메서드의 파라미터로 들어오니 그에 상응하는 ‘응답’을 해 줘야 한다. List와 같은 덜 추상화된 상태는 메서드의 리턴 이후에 어떤 일이 일어날 지 다시 한 번 생각하게 만든다. 추상화 수준의 간극으로부터 발생하는 인지적 부담이라고 생각했고, ResponseEntity로 감싸야 한다는 결론에 이르게 되었다.

나의 철학을 배경삼아 결론을 이끌어내니 즐겁고 짜릿했다! 나의 의견에 깊이 공감하는 크루들도 있었고, 여전히 자신들의 철학을 바탕으로 반대 의견을 이야기해주는 크루도 있었다. 다양한 이야기를 하면서 자신만의 코드 철학을 다져나가는 것 같아 서로가 기특했다! 앞으로도 여러 선택지에서 고민할 때, 나의 경험이 바탕이 돼 도움이 되는 순간이 있으리라 생각한다 💪🏻

🔥 이번 주는요

매주 테코톡 주제 뭐 하지… 라고 징징대던 내가 두 번째로 테코톡 신청을 넣게 되었고, 2레벨 첫 테코톡을 담당하게 되었다. 이제 2주 정도 남았는데, 열심히 준비해서 10분 안에 크루들과 나의 철학을 나누고 싶다는 생각!

아자아자

이번 주 유독 아픈 크루들이 많다. 마스크를 쓰는 얼굴이 하나둘 늘어나기 시작하더니, 나도 수요일부터 골골대다 금요일까지 힘들게 지냈다. 오한이 가시질 않아서 코로나인가 했지만 막상 검사해보니 아니었던.. 그래서 더 억울해 🥹 학습하는 것보다 중요한 건 학습하기 위한 몸과 마음이 준비돼야 한다는 걸 다시금 깨닫는다. 모두 아프지 말고… 건강하게 롱런해요… 🏃

Categories