작가들의 두런두런
팀에서는 코드 퀄리티에 얼마나 신경을 쓰시나요?
저는 좋은 코드를 생산하고, 이력을 관리하고, 문서를 작성하는 게 타인과 미래의 나를 위한 일이라는 것을 알고 있는 동료들과 일을 하고 있어요. 우스갯소리로 ‘좋은 코드와 양질의 문서 작성이 잘되어있으면 인수/인계가 편하다.’라는 말도 합니다.
저희 팀에서는 소나 큐브(Sonarqube)를 통해 정적 분석을 하고, gocd를 통해 지속적 배포를 하고 있고, 코드 품질을 높일 수 있도록 화기애애한 분위기 속에서 코드리뷰도 하고 있습니다.
이전 회사에서는 품질을 전혀 신경 쓰지 못한 적도 있었는데, 당시에는 코드에 대한 주인 의식이 부족했던 것 같기도 해요. 충분히 고민할 만한 시간도 주어지지 않았고요. 결과적으로 성장의 기회를 갖기 위해 프로젝트가 끝나고 이전 동료들과 작별했어요. early exit. 굳.
코드 퀄리티를 위한 좋은 툴은 lint, github, gerrit, fisheye, crucible 들도 있을 것 같아요.
저희 팀은 코드리뷰를 중요시합니다. 원칙적으로 master/develop 브랜치에 직접 푸시를 금지하고 있습니다. PR(Pull Request)를 날려야 하고, 매 PR마다 rubocop, checkstyle을 통해 코드 분석을 하고, 테스트를 돌리고 있습니다. 모든 결과가 성공적으로 끝나면 코드 리뷰를 받고, 리뷰어가 merge를 해주고 있습니다.
저희는 프로젝트가 Ruby on Rails로 구성되어 있어서, Ruby의 SAT(Static Analysis Tool)인 rubocop과 checkstyle을 이용하고 있고, Ruby의 style guide를 기반으로 코드를 짜려고 하는 노력을 많이 합니다. 리뷰도 스타일 가이드에 기반해 진행될 때도 많고요. :)
CI와 클린 코드 도구들을 자동으로 연결해 놓고, 지속적으로 관찰하다 보면, 코드의 문제가 있는 부분이 계속 드러나고, 쉽게 리포트받을 수 있어서 좋아요. 단, 발행되는 리포트를 무시하면 안 되겠습니다.ㅎㅎ
어느 정도가 적정한 정도의 코드 클리닝일까요?
예시를 하나 들어보겠습니다. 유저가 사용할 수 있는 쿠폰을 조회하는 API를 작성했습니다. 이미 서비스 중인 API인데, 추가 스펙이 생겼습니다. 쿠폰을 조회할 시점에 조건에 맞는 쿠폰을 자동으로 할당해주는 기능도 필요하다는 스펙인데요. 어떻게 구성할 수 있을까요?
클린 코드의 관점에서는 단일 메소드 단일 책임 원칙에 따라, '등록 API', '조회 API' 두 개로 구분하여 클라가 서버에 두 번 찌르도록 하는 것이 맞을 것입니다.
하지만, 클라이언트 입장에서는 두 개의 API를 화면마다 쌍으로 불러야 하고, '등록'이 끝난 후 '조회 API'를 call 해야 한다.. 등의 제약들이 늘어날 것입니다. 클라이언트에서 두 번의 request를 보내야 하는 만큼 network time이 길어질 것이고요. 서버에서 한 큐에 끝내는 것이 속도 측면에선 더 빠를 것 같아요.
판단은 서비스 환경에 따른 개발자의 몫이겠지만, API 호출 시점에 따라 API를 두 개로 나눌 수도, 한 개로 합쳐서 제공할 수도 있을 것 같습니다. 등록과 조회를 앱 진입 시에 확인해야 한다면 반응 속도가 빨라야 하며 한 개의 API로 보내는 것이 나을 수 있습니다. API는 하나로 제공하되, 내부에서의 코드를 단일 메소드 단일 책임 원칙을 실천하고 복잡해지지 않도록 노력하는 것이 모두를 위한 타협점일 것 같아요. 클린 코드 만을 고집하기보다는 적절히 타협하는 점이 필요한 것 같습니다.
어쩔 수 없는 상황이 여러 개 묶여 있는 것 같네요. 서비스의 반응 속도는 서비스의 신뢰도와도 관계가 있다고 느껴질 수 있으니까요. 이럴 땐 융통성 있게 협의하는 것도 좋은 것 같아요. 개발자로서 클린 코드를 포기하기가 쉽지는 않지만, 상황에 따라 타협점을 찾아내는 것도 훌륭한 개발자의 덕목이라 할 수 있겠네요.
클린 코드와 관련해서 최근 후회되는 경험이 있으신가요?
코드를 두 번째 봤을 때 고쳤어야 했는데, 고치지 못했어요. 프로그램이 초기에 생각했던 것보다 비대해지면서 구조를 다시 잡았어야 했는데, 안일하게 기존 구조에 덕지덕지 기능을 추가해버렸습니다. 누더기가 된 코드는 빠르게 레거시가 되어 아무도 건드리기 싫어하는 코드가 되어버렸습니다. 코드의 더러움이 일정 이상 상승하면 ‘아, 다시 만들까…?’ 싶은데, 지금이 딱 그런 것 같아요. 서비스 중인 product라 건드리기는 애매하고, 놔두자니 창피하고…
그런 경우가 있을 수 있죠. 리팩토링 할 만한 일정이 나오지 않았다던가, 당시에 너무 귀찮았던가..
코드를 고칠 때 한 번에 제대로 고치지 않으면, 나중에 시간 내기가 참 어려운 것 같아요. 한가하면 모를까, 다른 일로 치이고 있는 상황에서 동작하는 레거시 코드를 리팩토링 하는 시간을 별도로 할애하는 건 많은 이해가 필요한 것 같아요. 물론 리팩토링을 하면 좋다는 것을 모두가 알고 있지만 시간은 제한적이라…(변명 변명)
어떻게 클린 코드를 시작하면 좋을까요?
첫 번째로 코드리뷰를 할 때, 리뷰어들이 코드를 읽을 때 '아 이게 무슨 말이야!?'라는 말은 듣지 않도록 가독성에 초점을 두고 코드를 작성하면 좋을 것 같아요. 팀 내의 컨벤션이 있다면 컨벤션에 따르거나, 언어의 스타일 가이드 문서를 정독하고 하나씩 적용해보는 것도 좋은 방법인 것 같습니다.
100% 완벽한 코드는 없는 것이고, 모든 코드는 시간이 갈수록 레거시가 됨에 따라 처음부터 완벽을 추구할 필요는 없다고 생각해요. 작은 것 하나에서 시작하고, 꾸준히 노력하는 것이 정답이라고 생각합니다. 예를 들면 이번 주에는 '변수명/메소드명'에 어떻게 나의 의도를 잘 녹여볼지 집중을 하고, 그 부분을 집중적으로 리뷰를 받는 것이지요. 현재 개발하고 있는 프로젝트에 적용하는 게 리뷰받기에도 좋지만, 정말 상황이 여의치 않을 경우 개인적으로 혹은 과거에 작성했던 코드를 리팩토링 하는 것에서부터 시작할 수 있을 것 같아요.
그것조차 여의치 않다면 적어도 개선이 필요한 부분을 파악하고 있는 것만으로도 도움이 될 수 있고, 케이스에 대해 학습을 하면 도움이 될 것 같습니다. 학습하다 보면, 추후 다른 프로젝트의 일정 산정에 아름다운 코드를 짜기 위한 일정도 같이 고려해볼 수 있을 거고요.
작가들의 클린 코드에 대한 생각을 적어보았습니다.
여러분들이 생각하는 클린 코드는 어떤 코드인가요?^^