본문 바로가기
회고/여을심은 열심중 2022회고

여을심은 그동안 어디서 뭘 했을까

by 6161990 2022. 11. 4.

백문이 불여일타

입사 후 5개월 쯔음인가. CTO님과 페어를 하다가 엄청 혼났다. Optional 로 구현된 로직의 테스트 케이스를 성공시켜보라고 하셨는데, 내가 거기서 아둥바둥대며 아무것도 하지 못했다. 그동안 공부를 나름 한다고 해왔는데, 조금의 압박감으로 아예 머릿속이 하얘지는 게 바보같았다. 이 날을 계기로 그동안의 공부방식을 되돌아봤었다.

1월 1일을 제외하고 매일 수련했다. 1월 1일은 왜 빠뜨렸냐면.. 1월 1일부터 수련한다는 사실을 까먹었기 때문..습관이 이렇게 중요하다..

 

나는 머리만 커지는 공부를 하고 있었다. 이런 저런 지식만 쌓고 막상 구현하려면 손이 느리고 내 것으로 만든 적이 없으니까 응용도 하지 못하고, 좀만 코드가 달라져도 이해하는데 많은 시간이 걸렸다. 머리보다 손이 빠른 공부를 해야겠다 다짐했다. 학学보다는 습习에 많은 시간을 투자하기로 한거다. 블로그를 잠시 중단한 이유다. 블로그 포스팅은 생각보다 많은 시간이 걸린다. 공유를 통해 스스로 생각을 키워내고 정리하는 것보다 손을 빠르게 하는 것에 집중하기로 했다. 왜냐면 그게 더 멋있으니까.. 전자는 다른 방법들로 훈련할 수 있지만 후자가 되는 것은 딱 한가지 방법밖에 없었다. 연습 , 연습 , 연습….

 

습을 위한 3가지 Action Item 

 

▶️ 1일 1커밋에 대하여 : 습习

더보기

말 그대로 '습习'을 위한 습관들이기 였다. “타자치는 시간을 절대적으로 늘리자, 그래서 머리보다 빠른 손이되게 하자” 가 목표였다. 실제로 이렇게 나 자신과 약속을 하고 습관을 들이니 코딩 한 줄이라도 더 치게되는 건 사실이었다. 주말에 늦잠을 자거나 약속이 있어도 인텔리제이를 열어서 손을 운동시켰다. 이 습관때문에 코딩 실력이 엄청나게 늘었는지는 잘 모르겠지만, 책이나 인강에게 의존하는 것보다 손을 먼저 움직이려는 훈련은 된 것 같다. 1일 1커밋으로 공부했던 리스트는 다음과 같다.

근데 여기에 하나 더 추가해보고 싶은 건, 나만의 코드다. 내 개인 프로젝트로 1일 1커밋을 진행해보려고 요즘 준비중이다.

 

 

▶️ 쓸모가 있는 공부를 하자

더보기

개발자가 공부해야 할 목록은 길고도 길다. 왠지 전부 다 알아야할 것 같은 조급함이 든다.. 그래서 나는 올해 초, 모든 목록을 하나씩 타파하자는 전략을 세웠었다. 인터넷 강의를 처음부터 끝까지 매일매일 들었다. 내가 지금 그 기술이, 구현 방법이 필요없다라도 말이다. 쓸모없는 시간을 만든 것 같다는 생각이 들었다. 쓸모가 없는 공부는 지금하지 않아도 될 공부라는 결론에 다다랐다. 인강으로 restTemplate 테스트를 한번 익혀봤자, 쓰지 않으면 다 까먹는다. 필요할 때 구글링으로 배워도 충분하다는 생각이 들었다.

 

관심 가는 것, 회사에서 쓰이는 것 , 내가 당장 내일 일을 할 때 필요한 것을 기준으로 공부 토픽을 잡았다. 내 빈틈을 능동적으로 메우고 새로운 배움으로 인해 알게 된 새 빈틈을 목록에 추가하는 식이었다.

 

그 다음엔 내가 그 빈틈을 더 깊게 파고들지 아니면 또 다른 공백으로 관심을 돌리는 것이 생산적일지 정했다. 모든 기술을 연마할 시간이 없었기 때문에, 절충하는 법을 배웠다.

 

 

▶️ 레퍼런스를 자주 들여다보자.

더보기

레퍼런스를 참고하고자 한건 CTO 님의 제안 덕분이었다. CTO님과 매일 함께 읽기를 진행했다. 테스트 관련 레퍼런스부터 파고들기 시작했다. 읽는 방법은 다독이었는데 아래처럼 일독마다 방식을 다르게 했다.

 

해당 방법이 괜찮은 것 같아 팀원들에게도 공유했다

 

스프링 테스트 레퍼런스를 참고 하면서 배우고 익히게 된 것들을 챕터별로 정리해두었다.

 

 

몇몇 건들은 도움이 많이 되어서 회사 테크톡에서 발표도 했고, 전체적으로 스프링에서 junit 이 테스트 되는 플로우를 공부할 수 있었다. 이게 실무에서 테스트 코드를 짜는데 많은 도움이 되었냐 하면 그렇진 않았다. 이론적으로 배우는 것과 실제로 어떤 테스트를 해야하느냐 를 생각하는 건 다른 영역이었다. 깊이 있게 배우는 것도 좋지만 나는 좀 더 실용적인 공부를 원했다. 그래서 5독 까지 진행하고 레퍼런스 읽기를 그만두었다. ('습'을 본격적으로 공부해보자 한 시점부터다.) 지금 생각해보면 그때 공부한 것들 덕분에 junit, mokito 가 제공하는 기능을 이해하며 사용하고 있다. 레퍼런스를 보는 것이 내가 사용하는 도구를 깊이있게 아는 것에 도움이 된다고 느꼈기 때문에 조금씩 자주 들여다보는 습관을 해야할 것 같다.

 

 

가장 크게 배웠던 공부 토픽 3 가지 

▶️ 테스트 

더보기

나는 테스트 코드를 작성할 줄 모르는 사람이었다. 왜 작성해야하는지도 모르는 사람이었다. 현재는 이 둘을 모두 깨달아가는 과정 중에 있다. mock이 어떻게 쓰이는 라이브러리인가. 나는 답하지 못했다. 내가 속한 팀은 주로 테스트 코드로만 코드 리뷰를 진행했다. 그만큼 테스트 코드를 중요하게 생각하는 팀이었고 TDD 지향 개발자가 많았다. 처음에는 스프링 프레임워크에서 테스트 도구들이 돌아가는 원리를 공부했다. 근데 그 원리보다 중요한 건 테스트 코드를 이해하는 맥락인 것 같았다. 현재 주고 받는 메세지를 잘 드러내고 어떤 협력을, 누구와 하고 있는지를 누가 봐도 알 수 있게 잘 전달하는 것이, 테스트 도구 자체를 이해하는 것보다 더 중요한 일 같아보인다. 결제 환불 원장을 구현하면서 차츰 테스트 코드의 중요성을 깨달았다.

 

처음 스스로 짠 테스트코드는 이런 식이었다. 단언문이 많거나, 중복을 피하기 위해 setUp메소드로 모두 몰아 넣는 식.

 

setUp메소드로 모두 몰아 넣는 식

 

조금의 경험을 하고 리뷰까지 거친 뒤의 코드는 다음과 같다. 

 

같은 맥락 안에서 공유 되어야 할 것들은 중복이더라도 함께 두었다.

 

기본이라 할지도 모르겠지만 내가 아닌 누군가 테스트 대상 로직을 다듬어야한다는 것을 생각하면 당연하지만 중요한 일이었다. 테스트 코드는 비즈니스를 이해하는 데 도움이 되어야한다. 가독성과 명확성이 그래서 중요할 것 같다. 다른 개발자가 다른 피쳐로 해당 레포를 열었을 때, 더 쉽고 빠르게 그리고 덜 부담이 되게 다져놓아야한다.... 명심하자..  테스트 코드도 리팩토링을 계속 해야한다. 자주 들여다보쟈.

 

테스트를 다듬으면 다듬을수록, 메인 코드도 함께 개선이 되는 것도 느꼈다. 테스트를 했는데 assert와 검증 대상 로직 간에 주고받는 맥락이 한눈에 드러나보이지 않을 때가 있었다. 

 

설명을 위한 예시 코드 입니다.

일정 시점으로부터 시간이 얼마나 흘렀냐에 따라 결정지어지는 Key가 있었다. 그 기준을 ‘월’ 단위로 잡았는데, 이 정보를 모르는 사람이 보면 RoundIndex 가 왜 3인지 모를 것 같았다. 그래서 다음과 같은 고민을 했다.

 

우선, 빌더 패턴을 이용해서 만든 given 절을 없애고 decide() 인자로 넘겨 더 직관적 비교가 되게끔 했다. 원래는 내부에서 repository 통해 roundIndex를 찾았었다. 그 행위를 밖에서 진행하는 것으로 변경한 것이다. 필요없는 코드도 사라지고 테스트 코드에서 시간의 흐름을 더 간결하게 볼 수 있었다. 테스트 코드 내에서 이해도를 높이기 위해 monthDiff() 메소드를 만들었다. monthDiff 는 아주 단순한 도우미 메소드다.

 

 

여기까지 생각이 흐르다 보니, 이런 고민도 하게 되었다. “month 를 기준으로 비교한다는 걸 밖에서 전달 해주면 어떨까.”

 

 

테스트를 잘 짜려고 노력하다보면 고민하게 되고, 고민하는 시간을 갖다보면 메인 코드에 대한 개선도 찾게되고, 설계가 나아지고, 디자인에 대해 다시 생각해보게된다. 이런 테스트의 선순환이 테스트를 하는 이유이지 않을까. 시간이 흐르면 어떤 코드든 레거시가 될 것이고, 내가 아닌 누군가는 그 코드를 이해해야하는 순간이 온다. 테스트의 가독성이 높아야하는 이유는 그래서이지 않을까. 길고 긴 셋업 메소드가 있다면 그 당사자는 테스트 추가를 꺼려할거고, 건강한 선순환이 일어날 수 없을 것 같다. (당장 내가 그런 코드를 보면 두려움이 앞선다ㅠ)

 

지금 돌이켜 생각해보면, 이랬다면 어땠을까. 저랬다면 어떨까. 하는 아쉬움도 있다. 또 고민 끝에 개선한다고했지만 그렇게 좋은 개선이었는지는 의문인 케이스도 많다. 해당 RoundIndexDecider의 구현체의 비교 기준이 앞으로 절대 바뀌지 않아야한다면, 밖에서 전달해줄 필요가 있을까? 하는 생각도 든다. 또한 불필요한 세부정보를 너무 드러내려고 했나? 같은 생각도 든다. 하지만 나는 다른 개발자가 테스트의 의도와 핵심을 한번에 파악하는 데에 더 중점을 두었다. 어느 쪽에 더 가치를 둬야할지 아직도 확실한 판단은 서지 않는다. 매번 고민하고 있다. 분명한 것은 안전장치로써의 테스트가 아니라 작성하면서 깨닫는 도메인 가치와 단위 테스트로 빠른 피드백을 받으면서 경험하는 사고과정. 이 두 가지가 테스트를 잘 그려내고자했던 맥락 안에서 일어났다. TDD 는 무에서 유를 엘레강스하게 창조해주는 것 같다.

 

 

▶️ 디자인패턴

더보기

디자인 패턴 공부의 첫 시도는 실패였다. 매일 하나씩 패턴 하나를 공부한다고 해도, 내 것이 되는 것에는 한계가 있었다. 지금 생각해보면 엑셀 모든 기능을 다 알고 사용해야지 같은 바보같은 다짐과도 같았던 것 같다.. 디자인 패턴은 필요할 때마다 찾아보며 익히는 방법이 맞을 것 같았다. 거기에다 각 패턴의 효용을 내 스스로 느껴야 써먹을 수 있을 것 같다.

 

어떤 이벤트 버전이 오던지 수용 가능한 도메인을 만들기 위한 어뎁터 클래스

그니까 이런거다. 어댑터 패턴을 처음 익혔을 때 Volt(볼트) 예제로 공부했었다. 그때는 다 익혔다 생각했지만, 응용을 할 때엔 잘 적용되지 않았다. 어뎁터 패턴을 정확히 이해하게 된건 회사 프로젝트를 진행하면서였다. 어떤 이벤트 버전이 오던지 수용 가능한 도메인을 만들기 위해 중간에서 어댑터가 도메인에 적용시킬 수 있게끔 변환시켜 주는 방식이었다. 이 구현을 하면서 해당 패턴을 수련했다. 그래서 앞으로 디자인 패턴 공부를 따로 안할거냐. 하면 그렇지 않다. 좋은 것을 봤던 눈이 있어야 좋은 그림을 그릴 수 있으니까, 그림으로써의 패턴을 익혀나갈거다. 구체적인 구현 코드 예제가 아니라 커다란 그림말이다. 흘깃 쳐다본 경험으로는 디자인 패턴도 결국 정답은 없고 패턴과 패턴끼리의 교집합이거나 차집합이거나 합집합이거나 그도아니면 새로운 변종의 탄생이거나 그런 것 같았다. 적재적소에 적용할 디자인이 없다면, 내가 그려야지 뭐.. 그럴 수 있도록 좋은 그림을 평소에 조금씩 접해두어야지 하는 생각이다.

 

▶️ 자바 Stream

더보기

자바를 주언어로 개발하고 있지만, 자바 스트림 연산에 대해서는 깊숙히 알지 못했다. 리스트에 있는 값 중 , 가격만 매핑하여 총액을 구하는 로직을 구현해야했다. 그 다음에는 같은 상품끼리 그룹화가 필요했다. 스트림 연산을 이용하면 쉽게 구현할 수 있을 듯 싶었다. 근데 나는 자바 스트림 연산의 sum도, grouping 도 알지 못했다. 빈틈이었다. 빈틈이 있으면 메워야지.

 

람다, 스트림은 객체 지향인 자바 코드에서 함수형으로 프로그래밍 할 수 있는 방법이다. 객체지향 언어를 다른 접근 방식으로 공부하는 것도 좋겠다 싶었다. (이런 접근 방법에 부작용이 있을런지도 모르겠다. 예를들면 자바로 함수형 프로그래밍을 공부하는데, 자바 스트립트도 아예 똑같을 거라 생각하는 사고 방식이다..함수 지향의 사실과 오해가 생길 수 있다는 말이다 😂

 

9~10월 간 ‘모던 인 자바‘로 공부했다. 혼자 공부를 하다가 관심있는 팀원이 생겨 조인했다. 매일 아침 여덟시부터 열시까지 우리는 모각코를 하고 공부한 내용을 공유했다.

 

자바 8에 대한 전반적인 변화를 공부하면서 처음 느낀 것은 '동작 파라미터화'의 위력이다. 메서드 인자로 동작할 수 있는 기능을 넘기면 내부적으로 다양한 로직을 수행할 수 있다는 거다. 빨간 사과든, 파란 사과든 무게가 100kg 가 나가든 10kg 가 나가든 간에,  사과의 속성에 대한 모든 변화에 대응할 수 있는 유연함을 가질 수 있게 되는 것이 핵심이다. 내가 전달한 Predicate 객체에 의해 사과를 필터링하는 메서드의 동작이 결정되는 것이다. 이렇게 하면 컬렉션 탐색 로직과 각 항목에 적용할 동작을 분리할 수 있다!

 

나는 여기서도 다른 곳에 적용할 수 있는 깨달음을 하나 얻었는데, 모든 것을 최후로 미루자 전략 이다. 내부가 아니라 그 바깥 최후 경계로 결정을 미루면 설계는 자유로워지고 코드는 유연해지는 걸까 ? 같은 생각이다. 아직 확답을 얻을 수는 없는 단계고,, 뭐 그냥 그런 생각이 들었다는 말이다.

 

 

 

스트림 공부를 하면서 알게된 flatMap을 시험해본 코드다. 여러번의 개선 끝에, 다소 복잡하지만(정산 도메인인이라 원래 조쿰 복잡하다..) 이전 코드에 비해 forEach 문이 하나 빠졌다. 성능적으로 이게 더 좋은지는 잘모르겠다. 스트림을 사용할 때에 생각보다 성능이 좋은 것도 있었고 그렇지 않은 케이스도 있었다. 이런 부분에 대해서도 공부를 해보고 있다. 깊게는 안할거다. 필요할 때 해야지.. 난 다른 걸로 채울 것이 너무 많다.

 

 

(+) 추가 , 스트림 parallelStream 성능 테스트

소량의 데이터에서는 병렬 스트림이 도움 되지 않는다...!

 

 

2022년,

개인 공부는 위와 같이 진행했고 현재는 개인프로젝트를 진행중이다. 내가 작년 2021 회고에서 하고 싶다고 했던, 릴레이 소설을 실제로 만들어보고 있다!!!!!!! 🍑🤍💙 너무 행복하당 🍑🤍💙 

진짜 실현이 되다니.............. 윤지의 상상은 현실이 된다 유노

 

한편, 여을심은 도메인 주도 개발에 흥미를 붙여서 DDD-도메인 주도 개발도 공부하고있다. 내가 회사에서 진행했던 큰 프로젝트 두 가지가 알고보니 DDD 방식 로 진행한 거였다는 사실을 깨달았다! cto 님이 자연스럽게 그 길로 인도해주신 것 같다. 그 책을 읽고 있으면, 다 cto 님이 말씀해주신거다. 글로 DDD를 배우지 않아서 다행이었던 것 같다. 실제로 DDD를 해봐서 이 책에서 말하는 내용이 덜 어렵게 느껴진다. ㅎ 앞으로 좀 더 공부해볼 생각이긴한데, DDD 를 지향하지 않는 사람들의 개발 방식과 생각도 궁금하다. 

 

+) 

아! 그리고 여전히 1일 1글과 책읽기도 진행중이다. 짧게만 얘기하면 올해 가장 재밌었던 책은 <고래> 와 <물고기는 존재하지 않는다> 다. 

 

 

 

다음 포스팅에서 회사에서 작업했던 프로젝트 회고 해보려고 한다. 개인적으로 올해 성장에 큰 도움이 되었던 것들이라, 너무 소중하다. 회고를 위한거니까 나는 최대한 많이 회고를 할거고 그래서 엄청 길고 지루한 글이 될 수도 있을 것 같다.