[시작하면서]
프리코스 첫 주차 onBoarding 미션을 진행하기 직전 진행했던 1시간 가량의 OT에서 가장 마음에 와닿았던 내용으로 1주차 회고를 시작하고자 한다.
“현장에서 정말 중요하게 생각하는 역량들이 많은데 프로그래밍 구현 역량, 설계 역량, 추상화 역량 등이
개발자 역량으로서 가장 중요한 것들이라고 생각한다.”
“지원자들이 우아한 테크코스 프리코스를 이수하며 얻어가길 원하는 바는 가독성이 좋고 유지보수가 수월한 코드를
설계하고, 이를 테스트 할 수 있는 코드를 작성하는 법을 배워가는 것이다.
이를 잘 배워간다면 어디에서든 잘 일할 수 있다.”
개인적으로 위에 언급한 내용이 우아한 테크코스를 진행할 때 뿐만이 아니라 앞으로 개발자로서 커리어를 시작하게될 모든 이들이 명심해야 할 내용이라고 생각했다. 또한 프리코스 과정을 단순하게 본교육 과정을 가기위한 테스트라고 생각하는 것이 아니라 한 달 과정의 본교육을 이수한다고 생각하고 임해야 겠다고 마음을 먹게 되었다.
[Preview]
과제 완성을 어렵게 했던 가장 주된 원인은 문제 요구사항의 모호성이었다. 일반적인 코딩테스트 문제의 경우 예외 상황을 철저하게 검증하여 문제에 조건으로 제공하는 것이 일반적이다. 하지만 프리코스의 과제들은 공통적으로 요구사항이 100% 명확하지 않았다. 문제 요구사항을 아무 생각 없이 읽으면 그냥 구현하면 되겠구나라고 생각하기 쉽다. 하지만 실제로 구현하다 보면 막연한 요구사항으로 인해 개발자의 주관으로 결정해야 하는 사항들이 존재한다. 또한 문제에는 주어지지 않았지만 반드시 다뤄져야할 예외 상황들도 존재했다. 어디서 뭘 놓친걸까라고 고민하던 찰나에 과제 진행 방식에 명시된 한 줄의 내용이 눈에 들어왔다.
이를 통해 요구사항의 모호함은 의도된 것이라 결론짓고 스스로 옳다고 생각하는 프로그램의 방향을 설정하며 구현하였다. 이후 코치와의 수다 타임(코수타)에서 1주차 과제에 대한 질문사항을 받는 중 코치님들은 대다수의 지원자가 느낀 모호함이 의도된 것이 맞다는 확답을 해주셨다. 현장의 요구사항들은 훨씬 더 명확하지 않으며 프리코스 주차가 지날 수록 요구사항의 모호함은 더 심해질 것이라 예고하셨다. 이에 대해 소프트웨어라면 이래야 한다고 스스로 생각해서 결정하고, 가장 좋은 방법이라 생각되는 것을 적용해서 구현하라고 조언을 해주셨다. 예전에 프로젝트 요구사항 명세서를 직접 작성하며 머리가 터질 뻔 했던 것을 경험했던 나로써는 너무나 깊이 와닿는 부분이었다.
[Commit]
과제를 진행하며 겪은 첫 번째 어려움은 기능 단위로 commit을 해야한다는 것이었다. commit을 기능 단위로 해야 한다는 것은 익히 알고 있었지만 왜 그렇게 해야 하는지도 몰랐고 습관도 전혀 들어 있지 않았다. 그래서 개발하다가 멈추고 다시 기능별로 commit 하고 개발하는 식으로 진행하며 습관을 들이려 노력했던 1주차였다.
자연스럽게 알게 된 점은 기능별로 commit을 하면 수많은 코드 중 어떤 부분이 특정 기능을 위해 구현된 것인지 바로 알 수 있다는 것이다. 추후 commit log를 보며 유지보수를 진행할 때에도 어디 부분을 찾아가서 시작해야 하는지도 바로 알 수 있다. 때문에 나중의 작업 효율성을 생각한다면 commit은 반드시 기능별로 이루어져야 함을 알게 되었다.
동일한 이유로 commit message 형식을 맞추는 습관을 들여야 한다는 것을 알게 되었다. 해당 코드 부분이 1차적인 기능만 구현된 것인지, refactoring이 얼만큼 이루어진 코드인지, 이전 commit이 기능적인 부분을 수정한 것인지 아니면 단순히 가독성을 위한 코드 포맷팅만 진행한 것인지 commit message만 보고 알 수 있도록 해야한다. commit message convention을 찾아서 공부하고 과제에 적용을 하며 쌓이는 commit log들을 보니 그 효과를 체감할 수 있었다. commit 내용을 일일이 보지 않아도 몇 번 문제의 어떤 메소드를 구현해서 commit했는지 바로 알 수 있었다. 프로젝트 규모가 커지면 커질수록 가져다 주는 이점 또한 커질 것이기에 반드시 습관화 해야겠다고 다짐했다.
[요구사항 분석 & 기능 설계]
두번째로 겪은 어려움은 요구사항을 통해 구현할 기능을 정리하고 이를 기반으로 개발을 진행하는 것이었다. 지금까지는 기능 하나 하나를 구현하는 것에만 급급했고 개발 전에 기능 설계를 먼저 진행했던 적은 한 번도 없었기에 굉장히 어색했다. 요구사항을 충족하기 위해 필요한 기능들을 정리하고 기능 별로 구현해야할 메소드를 먼저 정리했다. 기능 설계를 완료하고 개발을 진행했으나 실제로 메소드를 구현하면서 내부에서 또다른 메소드로 뽑아내서 정의할 수 있는 부분들이 굉장히 많았다. 스스로의 기능 설계 능력이 얼마나 부족한 지 뼈저리게 느끼게 해준 1주일이었다.
특히 7번 문제의 경우 처음 문제를 풀기 전에 요구사항을 정리하고 기능 목록을 작성한 뒤에 코드 구현을 시작했음에도 중간에 수정/추가 해야할 내용들이 너무 많아서 방향을 잃고 시간을 많이 투자했다. 하나의 기능을 구현하더라도 세부적으로 분석해 더 메소드화 시킬 수 있는 부분은 없는지 항상 고민하며 코드를 짜는 연습이 필요할 것 같다.
(7번 문제에 대해 작성한 기능설계 목록 마크다운 링크)
개인적으로 얻은 교훈은 메소드의 기능은 한 마디로 정의되어야 한다는 것이다. 처음 메소드 기능 명세를 작성할 때 간결하게 작성하는 법을 몰라 많은 시간을 소요하는 것이라 생각했다. 하지만 막상 알고보니 단일 메소드가 여러 기능을 수행하도록 설계하고 명세하려고 하니 한 마디로 정리하기가 어려웠던 것이었다. 앞으로 한 마디로 메소드를 정리하기 힘들다면 메소드가 정말 하나의 기능만을 수행하도록 설계된 것인지 다시 검토할 수 있도록 해야겠다.
[One level of indentation per method]
하나의 메소드는 한 번만 들여쓰기를 허용해야 한다는 convention이다. 처음에는 단순히 코드의 가독성을 위한 것이라 보고 쉽게 생각했었다. 하지만 실제로는 과제를 진행하며 메소드 당 들여쓰기 한 번만을 허용하도록 구현하는데 시간을 많이 소요했다. 2중첩 이상의 반복문이나 반복문 속 여러 조건문들은 convention을 지키기 힘들게 만드는 주 요인들이었다. 간단한 기능을 수행한다고 생각했던 메소드에서도 신경쓸 부분이 항상 존재했었다.
신기했던 점은 들여쓰기 level을 1로 유지하다 보면 메소드 당 하나의 기능만을 수행해야 한다는 convention 또한 어느정도 자연스럽게 지켜진다는 것이었다. 들여쓰기 depth가 깊어지는 것을 막기 위해 코드를 분리하여 메소드를 만들고 보면 그 메소드는 하나의 기능만 수행하도록 분리된 경우가 굉장히 많았다.
또한 기능 별로 메소드가 구분되다 보니 중복 되는 코드가 refactoring되어 짧아지는 경험 또한 신선했다. 메소드의 재사용성이 향상되어 얻을 수 있었던 경험이었던 것 같다. 사소한 convention처럼 느껴진다 해도 convention화 된 이유와 지켰을 때의 이점이 반드시 있다는것을 기억하고 지키려 노력해야 한다는 교훈을 얻었다.
(내용 추가) - 6번과 7번은 당시 시간 압박감에 쫒겨서 기능 구현을 해내는 것에만 초점이 맞춰져 있었다. 그렇다 보니 indent 레벨을 1로 지키지 못한 부분이 너무 많고 어거지로 이것 저것 적용해보려다 보니 코드 자체는 굉장히 난잡하게 완성되어 버렸다. 그럼에도 indent 레벨을 1로 지켜보려고 시도했던 것에서 알게된 점을 정리한 부분이었고 누가 볼거라고 생각하지 않고 정리한 부분이었는데 캡틴 포비가 1 따봉을 눌러주었다... 그 때 당시 1주일 동안 삽질하며 매달렸던 고생이 헛된 게 아니었구나라고 생각하게 해준 고마운 경험이었다. (이것과는 별개로 혹시 회고 포스팅과 코드를 보고 물음표를 띄울 누군가가 있을까 노파심에 내용을 추가한다...)
[테스트 주도 개발]
개인적으로 이번 기회에 가장 많은 시간을 투자해보고 싶었으나 그러지 못해 아쉬웠던 부분이다. 하지만 왜 테스트 주도 개발을 해야 하는지는 확실하게 알게 되었다. 처음에 꼼꼼하게 기능 요구사항을 정리하고 구현했다고 생각했다. 하지만 나중에 테스트 케이스를 추가해서 테스트해보니 고려하지 못한 예외 사항들과 빼먹은 기능들을 발견하게 되어 수정할 수 있었다. 어떤 경우에서든 개발의 마무리는 테스트를 통해 이루어져야 함을 몸소 체험했다.
또한 기능별 commit을 위해서는 테스트 코드 작성이 필수 불가결하다는 것을 깨달았다. 하나의 기능을 수행하는 메소드를 구현하고 나면 commit해야 하는데 전체 프로그램 개발이 완료되지 않은 상황에서 해당 메소드가 의도한대로 정확히 동작할지 예측하기란 어려운 일이다. 그렇기에 구현한 메소드가 의도한대로 동작하는지 검증할 수 있는 테스트 코드 작성이 반드시 필요하다. 다음 과제부터는 요구사항과 기능 정리가 끝난 뒤 테스트 코드를 먼저 작성해 두고 이를 통과할 수 있는 코드를 구현하는 방식으로 진행하기 위해 노력해야겠다.
[Naming]
여담으로 개발자들이 왜 그렇게 변수와 메소드 naming을 어려워하는 지 알게 되었다. 7번 문제에서 사람 객체 내에 user와 친구 여부를 저장하는 boolean 속성 변수를 사용했다. 기존에 해왔던 대로 친구 상태 정보를 저장하는 변수니까 status 단어를 사용했는데 읽는 사람에게 참/거짓이 명백한 느낌을 줄 수 없다는 것을 공부하며 알게 되었다. 이후 refactoring 과정을 통해 변수명을 isUserFriend로 수정하였다. 변수명을 변경하니 user의 친구인지에 대한 정보를 담고 있는 변수라는 것을 바로 알 수 있었다.
메소드명을 naming 하는 것은 더 어렵게 느껴졌다. 메소드가 수행하는 기능을 이해하기 쉽게 naming 해야 하는데 메소드를 단일 기능만 수행해도록 설계하는 능력이 부족하다 보니 naming 또한 명확하게 하기 힘들었다. 예전에는 그저 웃고 넘긴 가벼운 밈이라고 생각했었는데 정말 중요하고 어려운 부분이라는 것을 이번 과제를 수행하며 알게 되었다.
[마무리]
위 내용들은 어떻게 하면 더 좋은 코드를 작성할 수 있을까 혼자 고민하는 과정에서 알게된 것들이다. 이후 공통 피드백까지 받고 공부해 나간다면 나중에 얼마나 더 좋은 코드를 작성할 수 있을지 기대감을 갖게된 1주차 프리코스 과정이었다.
'우아한테크코스 > 우테코 프리코스' 카테고리의 다른 글
[우아한테크코스 5기] 백엔드 지원, 합격 과정 회고 (합격 후기) (20) | 2023.02.06 |
---|---|
[우아한테크코스 5기] 프리코스 4주차 회고 (0) | 2022.12.22 |
[우아한테크코스 5기] 프리코스 3주차 회고 (0) | 2022.12.22 |
[우아한테크코스 5기] 프리코스 2주차 회고 (0) | 2022.11.08 |