"좋은 개발자로 성장은 어떻게 하는 걸까?"
개발을 하다 보면 내가 코드를 효율적으로 잘 작성하고 있는지 , 혹은 더 나은 개발자가 되기 위해 올바른 길로 나아가고 있는지 궁금해질 때가 많습니다. 좋은 개발자가 되기 위해 매번 노력은 하지만 기준이 모호했고 , 그 과정 속에서 생기는 고민들과 실패, 혹은 두려움들이 가끔은 자신을 힘들게 만들었던 것 같습니다.
최근에 싸피에서 특화 프로젝트를 진행하면서 2주 동안 크게 슬럼프가 왔었습니다. 저는 개발을 할 때 제 스스로에게 "왜"라는 질문을 많이 던집니다. 코드를 작성하더라고 이유가 반드시 존재해야 했고 , 왜 그렇게 동작했는지 , 더 효율적인 방법은 없는지 , 비즈니스 로직을 어떻게 풀어나갈지 고민하는 시간들이 필요했습니다. 하지만 프로젝트는 정해진 기간에 만들어야 했죠. 고민하는 시간들이 많아지니 다른 팀원에 비해 기능을 완성하는데 오래 걸렸고 , 점점 기여도에 차이가 나기 시작했습니다.
처음엔 내가 재능이 없는건지 , 남들에 비해 부족해서 고민하는 시간이 많았던 건지 스스로에게 자책을 많이 했습니다. 일주일 정도를 우울한 상태로 보내다 이러다간 안 되겠다 싶어 고민하는 시간을 줄이고 기능을 구현을 완성하는 데에 목표를 두고 팀원과 함께 조율해 나가며 해결하니 많이 회복하게 되었습니다. 이상하게도 구현을 완성해 놓고 돌아보았을 때 고민만 했을 때 보다 개선할 점이나 고려해야 될 부분들이 훨씬 더 명확하게 보였습니다. 처음부터 완벽하게 구현하는 것에 목표를 두는 것이 아닌 실행해 보고 테스트해보며 리펙토링 하는 작업이 훨씬 빠르게 진행되는 것을 깨닫게 되었습니다.
그래서 하고싶은 말은...💭
오늘 우연히 유튜브에서 알고리즘 추천에 우아한 테크에서 진행하는 "개발자 원칙" 라이브 방송을 보게 되었습니다.
"앞으로 고민하는 시간을 줄이고 기능 구현에 집중적으로 시간을 써야 하는지 , 어느 정도 수준까지 고민하고 넘어가야 하는지 , 방향을 어떻게 잡고 개발을 해야 될지" 에 대한 고민에 대한 해결책이 될 수 있는 강연이였습니다. 같은 취준생 혹은 개발자 분들에게도 좋은 강연 내용일 거 같아 정리해 공유해보려 합니다.
https://www.youtube.com/watch?v=DJCmvzhFVOI
[제어할 수 없는 것에 의존하기 않기 - 인프랩 이동욱]
어떤 개발자가 되고 싶으세요?라는 질문을 한다면 어떤 개발자가 되는 것이 좋을까 고민해 보자.
보통 이 고민에 대해서 정답을 내리긴 힘들다.
해당 책에서 프로그래머에게 요구되는 것은 100점이 아닌 80~90점짜리 프로그램을 기한 내에 완성하는 일이다. (나카지마 사토시)라고 말한다.
그럼 일정 안에만 만들면 되는 것일까?
그렇진 않다. 아무리 급한 상황이어도 80~90점짜리 소프트웨어를 일정 내 개발할 수 있는 것이 좋을 것이다.
그러면 일정을 항상 잘 지키는 사람들의 공통점은 무엇일까?
A라는 코드 B라는 코드, C라는 코드가 있다. 우리가 코드를 짤 때 이렇게 짜는 게 좋을까 저렇게 짜는게 좋을까? 하나의 코드를 짜더라도 여러 가지 고민을 하게 된다. 보통 예를 들어 내가 클린코드를 읽었다 하면 클린코드 규칙을 지키며 코드를 작성하고 객체지향패턴에 대해서 읽었다고 하면 객체지향적으로 코드를 짠다. 그때 그때 환경에 따라 고민을 한 끝에 코드를 작성하게 된다.
하지만 일반적으로 일정을 항상 잘 지키는 사람들은 가장 좋은 코드를 선택하는 본인들만의 원칙과 기준으로 빠르게 결정한다. 정말 중요하게 설계를 해야 하는 부분만 깊은 고민을 한다.
그래서 선택의 순간마다 고민하는 것보단 원칙에 따라 빠르게 결정하고 중요한 것만 고민하는 사람이 더 좋은 개발자라고 할 수 있지 않을까?
[제어할 수 없는 것에 의존하지 않는] 원칙
현실세계의 유니크 값인 주민등록번호를 고유 키값으로 사용했던 사례이다. 2014년 8월 7일부터 주민등록번호 수집/요구 금지가 내려져 이 값을 가지고 메인키로 사용했던 회사들은 설계를 다시 바꿔야 하는 상황이 발생하게 되었다.
1. 외부에서 전달받은 값은 절대 주요 키로 선택하지 하는 것을 피하자. 이 값은 제어할 수 없는 값인데 제어하려고 하면 다음과 같이 불상사가 발생할 수 있다.
2. SQL 보다는 애플리케이션에서 값을 다룬다. (password() , encrpyt().. ) 데이터베이스의 password라는 함수로 비밀번호를 만들 수 있지만 데이터베이스가 생성하는 로직이나 성능을 끌어올리기 힘들 수 있다. 내가 만드는 값이 아니기 때문에 최대한 배제하고 애플리케이션에 값을 다루려고 노력한다.
[제어할 수 없는 코드]
일요일이면 할인을 해주는 코드가 있다.
테스트 코드를 짰다. 하지만 제대로 작동하지 않았다. 왜냐하면 now() 함수를 제어할 수 없었기 때문이다. 월요일이나 화요일에 테스트를 하면 결괏값이 달라진다.
따라서 일요일에만 성공하는 테스트 코드가 되어버린다.
그래서 모듈 모킹을 통해 localDate라고 하는 모듈까지를 모킹 해서 LocalDateTime함수를 부르면 일요일에만 실행이 되도록 모킹을 하였다. 따라서 이 함수는 모킹을 통해 언제 수행하는 정확하게 일요일에만 수행이 되는 검증된 코드가 되었다. 그런데 이러한 코드가 문제가 없을까?
그런데 날짜 라이브러리를 바꿔야 하는 상황이 생기니 모든 날짜 모킹 코드를 변경해야 되는 일이 발생하게 되었다.
혹은 테스트 프레임워크를 교체해야 되는 상황이 발생해도 모든 모킹 코드를 변경해야 하는 일이 생긴다.
쓰고 있는 라이브러리를 바꾸고 싶은데 테스트 코드를 전부 다 바꿔야 하는 상황이 발생했다. 이것도 어떻게 보면 제어할 수 없는 값인 현재 시간이라는 코드에 함수가 의존하고 있으니 어떻게든 통과시키려고 모킹 해서 발생한 문제가 발생한 것이다. 즉 제어할 수 없는 값에 의존한 문제가 발생한다.
[제어할 수 있는 코드] 로 바꿔보자
제어할 수 없는 값인 현재 값을 함수 인자로 넘긴다. 즉 함수의 바깥으로 밀어내는 것이다. 그럼 우리가 받은 값을 가지고 값이 일요일인지 아닌지 판단하는 순수 함수가 만들어진다.
그렇게 되니 discount라는 테스트 코드를 작성하니까 일요일이라는 날짜가 들어오면 모킹이 전혀 필요 없지만 일요일에는 테스트가 성공하는지 토요일에는 실패하는지 검증하는 즉 제어할 수 없는 것에 의존하지 않는 함수가 작성이 된다.
따라서 제어할 수 없는 것에 의존할수록 변화해 쉽게 흔들리는 소프트 웨어가 만들어진다.
제어할 수 없는 것에 거리를 두고 제어할 수 있는 것에 집중하자.
[점염되는 제어할 수 없는 코드]
여러 강의들 중 결제 금액 계산 결과가 100원이 넘는 건들 만 골라서 PG 결제를 하는 메서드가 있다.
클린코드를 배웠으니 여기서 리펙토링 해서 함수를 하나씩 하나씩 추출해 본다고 가정해 보자.
리팩토링을 했더니 pay()라고 하는 함수 하나와 payAll()이라는 함수하나 그리고 payCourse()라는 함수 즉 3개가 나왔다.
- pay라는 함수에서는 강의 금액을 계산하고 강의 금액이 100원이 넘을 때는 RequestPg라고 하는 API를 호출한다.
즉 pay()는 강의 하나에 대해 결제만을 책임히는 함수가 된 거다.
- payAll()은 그 강의 전체를 돌면서 pay()라는 함수를 호출한다.
- payCourse는 다 통합하여 결과를 모달로 띄우는 등 통합 함수가 된다.
- 그런데 잘 보면 async await 외부 api를 호출하는 키워드가 모든 함수에 들어가 있다. 클린코드에 의해서 하나의 함수가 하나의 책임만을 지기 위해서 리팩토링을 했는데 리팩토링 결과가 결과적으로는 모든 함수는 외부 API를 모킹을 해야지만 성공할 수 있는 테스트 코드가 만들어질 수밖에 없는 환경이 되어버렸다.
그러면 왜 이런 상황이 발생했을까?
바로 제어할 수 없는 함수 하나가 있기 때문이다. 바로 async await 들어가 있는 requestPg이다. 이 함수에 의존하고 있는 모든 함수는 전염이 되어 다 같이 제어할 수 없는 코드가 된다.
따라서 제어할 수 있는 것과 제어할 수 없는 것에 대하여 코드 분리를 한다.
위에서 살펴보았듯이 requestPg는 제어할 수 없는 코드였다. 이것과 Modal이라고 불리는 함수만 payAll()이라는 함수에 올려두고 , 나머지 결제금액 계산과 100원 이상 걸러내는 것만 따로 만들어서 최종적으로 제어할 수 있는 것들로 나온 결괏값을 가지고 requestPg를 돌린다.
getCourseAmounts는 100원 이상의 강의만 걸러낸다.
getCourseAmount는 2개의 금액을 곱해서 실제 결제금액을 반환한다.
이 두 가지는 순수함수로서 단위 테스트가 가능해진다.
두 가지의 결과물은 모킹이 필요 없는 단위 테스트가 가능해지고 그 결과물을 가지고 외부 API를 호출하는 애는 모킹을 한다.
따라서 제어할 수 없는 코드란 순수하지 않은 함수 혹은 객체를 의미한다.
가능하다면 제어가능한 영역을 최대한 늘리고 제어가 불가능한 것들은 격리시키는 것을 원칙으로 코드를 작성하고 있다. (이동욱 CTO)
느낀 점..👀
저는 이 강의에서 언급한 것처럼 선택의 순간마다 고민을 하는 사람이었습니다.. 이는 나중에 협업을 하거나 맡은 업무를 수행할 때도 기한이 제한되어 있는 경우 치명적인 문제를 발생시킬 수 있다고 생각합니다. 그래서 앞으로는 원칙에 따라 빠르게 결정하고 중요한 부분만 고민할 수 있도록 저만의 원칙을 만들려고 합니다. 그리고 꾸준히 코드를 리팩토링을 통해서 클-린한 코드를 작성하려고 노력해 봐야겠습니다.
'Dev Diary' 카테고리의 다른 글
중복된 값을 저장하려고 할 때 HTTP 응답코드로 무엇을 반환해야할까? (0) | 2023.04.04 |
---|---|
TestCode ? 왜 작성하는거야? (0) | 2023.03.05 |
[시작] 개발 일기(?)를 작성해보려고 합니다. (2) | 2023.02.11 |