작년 11월에 Tom님과 Jaden님이 처음으로 페어 프로그래밍을 진행하고 도전기를 남겨주셨는데요,
그 이후로 API, 타이피스트 시스템 등 백엔드 애플리케이션을 중심으로 Pair Programming(이하 PP)과 Code Review(이하 CR)를 개발 문화로 정착시키기 위해 꾸준한 노력이 있었습니다. 본 글에서는 PP와 CR을 적용하면서 느꼈던 점들을 요약하여 말씀드리고자 합니다.
Why PP & CR?
PP와 CR을 해야 하는 이유에 대해서는 많은 article들과 서적에서 설명하고 있습니다. 따라서 저희가 실제로 경험했던 것 위주로 간단하게 핵심만 언급하고 넘어가겠습니다.
1. 품질 향상
혼자 코드를 작성할 때는 놓치고 갈 수 있었던 부분을 다른 사람이 함께 보면서 잡아낼 수 있습니다. 또 혼자 개발할 때는 ‘이 정도면 됐지 뭐’하고 스스로 합리화하고 대충 넘어가던 부분도 다른 사람이 내 코드를 본다고 생각하면 그렇게 하기가 어렵습니다. 아무래도 대충 작성한 코드를 남에게 보여주기는 민망하기 때문이겠지요. 그래서 코드를 한 번 더 확인하게 되고, 더 좋은 방법은 없는지 고민하게 됩니다.
구현에 앞서 설계 작업도 함께 하기 때문에 서로 아이디어와 의견을 교환하면서 더 좋은 결과물을 만들어냅니다. 백지장도 맞들면 낫다는 속담처럼 한 명이 아닌 두 명의 경험과 지식이 모였을 때 시너지가 나는 것이라 생각합니다.
따라서 장기적인 관점에서 전체 개발에 필요한 시간이 감소한다고 볼 수 있습니다. 버그가 감소하기 때문에 불필요한 디버깅이 없어지고, 설계가 개선되어 추후 디버깅을 하거나 기능을 추가 개발할 때 필요한 시간이 줄어들기 때문입니다. 어떤 유망한 회사에 투자를 하면 처음에는 가지고 있는 여유 자금이 줄어들어 손실로 보이지만, 장기적으로 손익분기점을 넘게 되면 큰 이득을 얻습니다. 마찬가지로 PP와 CR도 처음에는 시간과 노력이라는 투자가 필요하지만, 시간이 지나 성숙도가 올라가면 큰 이득을 얻는다는 것을 경험했습니다.
출처: http://martinfowler.com/bliki/DesignStaminaHypothesis.html
Martin Fowler는 Design Stamina Hypothesis라는 글에서 좋은 소프트웨어 설계를 위해서는 처음에 시간과 노력이 필요하지만, 일정 시점이 지나면 무설계 소프트웨어보다 훨씬 더 큰 생산성을 지속적으로 낼 수 있다고 주장합니다.
2. 지식 공유
PP와 CR하면 절대 이 부분을 빼놓을 수 없습니다. 두 명이 서로 협업을 하면서 자연스럽게 각자 알고 있는 도메인 지식과 best practice, 설계 기법들이 공유됩니다. 실제로 저와 Jaden님이 함께 Zeus 프로젝트를 진행하면서 이런 멋진 경험을 했습니다. Jaden님은 예전에 API와 타이피스트, 어드민 등 리멤버의 모든 백엔드 시스템 개발을 담당하셨기 때문에 사내의 어떤 누구도 따라올 수 없는 풍부한 도메인 지식을 가지고 있었습니다. 반면, 저는 오랜 기간 유연성과 확장성이 필요한 애플리케이션 개발을 진행하면서 어떻게 하면 좀 더 좋은 설계를 할 수 있을지 고민했던 경험이 있었습니다.
거의 두 달여간 매일같이 함께 PP를 하면서 서로의 지식이 완전히 sync되는 느낌은 흔치 않은 경험이었습니다. 이후에 Jaden님이 작성한 코드를 본 적이 있었는데 마치 제가 작성한 듯한 느낌이 들 정도였습니다. 아마 제가 작성한 코드를 Jaden님이 봤어도 같은 느낌이었을 겁니다.
이처럼 각자 알고 있는 지식뿐 아니라, 함께 코딩을 하면서 코딩 스타일, 컨벤션 등도 맞춰나가기 때문에 시간이 지나면 마치 한 사람이 작성한 것처럼 깔끔하고 일관성 있는 코드를 만들 수 있습니다.
3. 심리적 안정감
한 번도 가보지 않은 낯선 곳을 여행할 때면 아무래도 혼자보다는 동행이 있는 것이 더 든든합니다. 마찬가지로 PP와 CR을 하게 되면 누군가가 항상 옆에 있고 도움을 주기 때문에 심리적인 안정감을 얻을 수 있습니다. 그래서 코드를 커밋할 때도 좀 더 자신감 있게 하게 됩니다.
How to do PP?
7:3 Rule
아시다시피 PP는 두 명 중 한 명이 driver, 다른 한 명이 navigator가 되어 진행합니다. 그런데 해보면 driver보다는 navigator가 더 쉽게 지치는 것 같습니다. 두 명이 차를 타고 가면 운전자보다는 옆사람이 더 졸린 것과 같은 이치이겠지요. 따라서 특별한 이유가 없다면 driver와 navigator가 되는 시간의 비율이 7:3을 넘지 않도록 자주 바꿔주는 것이 좋다는 생각이 들었습니다.
그리고 driver와 navigator를 시간을 정해놓고 인위적으로 바꿀 수도 있겠지만, 제 생각에는 자연스럽게 바뀌는 것이 가장 좋은 것 같습니다. navigator 역할에서 뭔가 생각나는 게 있다면 바로 driver가 되어 코드를 작성해 보는 것이 더 자연스러운 흐름이기 때문입니다. 그래서, 각자 main driver가 되는 영역을 어떻게 나눌지 고민해보는 것이 필요합니다.
Main 코드에서 테스트 코드로
예를 들어 Jaden님과 제가 PP로 Zeus 프로젝트를 진행했을 때 처음에는 Jaden님이 테스트 코드 작성에 익숙지 않았습니다. 그래서 제가 메인 코드와 테스트 코드 모두를 작성하면서 어떻게 프로세스가 흘러가는지를 보여주었습니다. 약간의 시간이 지나서 Jaden님이 감을 잡게 되자, 메인 코드는 제가, 테스트 코드는 Jaden님이 작성하는 형태로 5:5의 비율을 맞추었습니다. 프로젝트 후반부에 가서 Jaden님이 완전히 익숙해지게 되자 메인 코드와 테스트 코드 모두 Jaden님이 작성하고 저는 주로 navigator 역할을 맡았습니다.
Tom님과 API 개발을 할 때도 마찬가지 방식으로 진행하였습니다. 이처럼 둘 중 한 명이 현재 코드베이스에 익숙하고 다른 한 명은 그렇지 못한 경우 익숙한 사람이 처음에는 main driver가 되고, 나중에는 익숙지 않은 다른 한 명이 main driver가 되어 실제 코드를 작성하는 것이 지식 습득에 가장 효과적인 것 같습니다. 들리는 후문에 의하면 Jaden님과 Tom님 모두 이 방식에 크게 만족하셨다고 합니다. 🙂
PP Details
저희의 경험을 바탕으로 PP의 장단점 및 주의사항을 간략하게 정리해보면 다음과 같습니다.
PP의 장점
- 개발자 간 의사소통이 CR에 비해 훨씬 더 즉각적이고 활발하게 일어나기 때문에 시간 대비 효율이 좋습니다.
- 서로 다른 분야의 전문가가 PP를 하게 되면 지식이 쌍방향으로 흘러가기 때문에 효과가 극대화됩니다.
- 이후에 혼자 코딩을 하더라도, 코드에 대해 좀 더 고민을 깊이하는 습관을 들일 수 있습니다.
PP의 단점
- PP는 고도의 집중력이 요구됩니다. 반나절만 PP를 해도 끝내고 나면 완전히 진이 빠지는 경우가 한두번이 아니었습니다. 이러한 피로도는 경험상 면접에 참여하는(면접관이든 피면접자이든) 피로도와 거의 맞먹는 것 같습니다. 따라서 오전이나 오후 시간만 하기 등으로 하루 중 일정 시간을 정해놓고 하는 것이 좋은 것 같습니다.
- 처음에는 서로 합이 맞지 않기 때문에, 진도가 매우 느리게 나갈 수 있습니다. 사소한 것에서도 서로의 생각이 다른 부분이 많기 때문에 여기에 대해 이야기를 하고 맞춰나가는 데 시간이 많이 걸립니다. 하지만 어느 정도 시간이 지나 서로 많이 맞춰진 상태에서는 굉장한 효율을 자랑합니다.
주의할 점
- 당연한 이야기지만 키보드와 마우스는 두 개씩 준비하는 것이 더 효율적입니다. 그래야 driver와 navigator 간의 전환이 빠르고 자연스럽게 일어납니다. 그렇지 않다면 navigator는 키보드를 뺏어오는 것이 부담스럽거나 귀찮아서, 보여주고 싶은 게 있어도 참고 그냥 지나갈지 모릅니다.
- navigator는 마음에 뭔가 걸리는 것이 있으면 꾹 참지 말고 거리낌없이 이야기해야 합니다. 예를 들어 개행, 공백, 변수명 등 사소한 것이라도 뭔가 다른 의견을 가지고 있으면 다 터놓고 이야기하는 것이 필요하다고 생각합니다. 그래야 서로 의견을 교환하고 맞추어나가는 과정에서 신뢰가 생깁니다. 또 코드의 일관성이 보장되고 좀 더 많은 지식이 공유됩니다. 반면 driver는 열린 마음으로 navigator의 이야기에 귀를 기울여야 합니다.
- 이처럼 서로 간에 허물없는 의사소통을 하기 위해서는 다시 한번 강조하지만 신뢰가 무엇보다 중요합니다. 이 부분은 Jaden님도 아래와 같이 잘 지적해주고 있습니다.
평소에도 마찬가지지만 특히 페어 프로그래밍을 할 때는 서로의 신뢰가 중요한 것 같습니다. 사람마다 실력차는 분명 존재하겠지만 개발이라는게 절대적인 정답은 없는거라고 생각합니다. 틀린 코드라는건 요구사항에 벗어나 개발된 코드를 말하는것이고, 요구사항에만 맞는 코드라면 모든 코드가 정답이라고 생각합니다. 단지 같은 요구 사항을 수행하면서도 누가 봐도 이해하기 쉽고, 효율적이면서 재사용 가능한 코드를 작성할 수 있다면 그건 좋은 코드라 할 수 있습니다. 페어 프로그래밍은 그런 좋은 코드를 작성 할 수 있도록 많은 도움을 주는것 같습니다. 그와 동시에 좀더 경험이 많은 사람으로 부터 노하우를 쉽게 터득할 수 있는 기회이기도 한것 같습니다.
- 같은 맥락에서 PP를 하기 위해서는 기본적으로 두 사람 모두 인성적으로 성숙해야 합니다. 자신의 의견만 고집하고, 다른 의견이 제시되었을 때 이를 자신에 대한 공격으로 인식하여 목소리를 높이는 사람은 절대 PP를 할 수 없습니다. 인격적 성숙과 신뢰가 쌓이지 않은 상태에서는 감정적 충돌이 발생할 가능성이 높습니다.
- 좀 더 효과적인 PP를 위해서는 PP를 위한 독립적인 공간을 마련해주는 것도 좋은 방법입니다. 실제로 저희는 PP를 위한 별도 공간을 만들어 언제든지 사용할 수 있도록 했습니다. 이렇게 하면 확실히 일반 사무공간과 격리되어 집중력이 향상되는 것을 경험했습니다. 또 PP를 하면 장시간 이야기를 굉장히 많이 하기 때문에 주변 사람들에게 방해가 될 수 있는데, 이러한 부작용을 방지할 수 있습니다.
How to do CR?
온라인 코드 리뷰를 위해서는 여러 가지 방법과 도구들이 존재합니다. 저희는 이 중에서 가장 쉽게 도입할 수 있는 Git의 Pull Request(이하 PR)를 사용해보기로 하였습니다.
Git Pull Request
PR을 사용할 때는 크게 두 가지 방식이 있는 것 같습니다. 하나는 원본 repository를 fork한 별도의 repository에서 PR을 생성하는 방법이고, 다른 하나는 같은 repository에 브랜치를 하나 만들어 여기서 PR을 생성하는 방법입니다. 저희는 이 중 브랜치 방식을 택하여 시도를 해보았습니다. 그 이유는 Tom님, Jaden님 모두 이미 git flow를 사용하고 있는 상황이었고, 또 같은 repository에 브랜치를 하나 만드는 것이 리뷰어가 코드를 받아 확인하고 실행하는 것이 더 쉽다고 생각했기 때문입니다.
위 그림과 같이 git flow의 convention을 사용하여 feature/profile(기능 추가 개발 시), fix/profile(버그 픽스) 등과 같은 브랜치를 만들고 여기에 관련 코드를 커밋 & 푸시합니다. 모든 작업이 끝나면 develop 브랜치로 PR을 하나 생성한 후 사내 커뮤니케이션 도구인 Slack으로 리뷰어들에게 리뷰를 요청합니다. 리뷰어들은 PR에 line comment를 달아 리뷰를 해줍니다.
필요하면 코드 리뷰를 더 재미있고 쉽게 만들어주는 PR 기반의 도구를 사용할 수도 있습니다.
요청자는 리뷰들을 다시 브랜치에 수정 반영하고, 2차 리뷰를 요청합니다. 이러한 과정을 3차, 4차 등으로 계속 반복할 수 있습니다(그렇지만 실제로는 2차 리뷰를 넘는 경우는 거의 없었습니다). 만약 리뷰 후의 수정사항이 간단하여 2차 리뷰를 굳이 받을 필요가 없다고 판단되면, 리뷰를 요청하지 않고 바로 머지할 수도 있습니다.
PR을 머지한 후에는 깔끔한 브랜치 관리를 위해 (특별한 경우가 아니면) 작업한 브랜치를 보통 삭제해주고 있습니다.
CR Details
PP와 마찬가지로 CR의 장단점 및 주의사항을 정리해보았습니다.
장점
- 코드 리뷰를 하면서 자신이 알고 있던 암묵지가 형식지로 변환됩니다. 예를 들어 요청자가 줄바꿈해놓은 것을 보면서 마음에 뭔가 걸리는 게 있을 수 있습니다. 그러면, 왜 이게 마음을 찜찜하게 만드는 건지, 또 내가 좋다고 생각하는 줄바꿈 방식이 왜 좋은 것인지 한참을 생각하게 됩니다. 이런 과정을 통해 요청자와 리뷰어 모두 기존에는 별 생각없이 당연하다고 여겨왔던 방식을 다시 한 번 곱씹어 보게 되고, 이를 comment라는 형태를 빌어 글로 작성하는 과정에서 그 이유를 좀 더 명확하게 깨닫게 됩니다. 따라서 CR도 처음 시작하면 comment를 쓰는데 생각보다 상당한 시간이 걸리는 것을 경험하였습니다.
- 아무래도 CR은 비동기로 일어나다보니, 시간을 관리하는 측면에서 편리합니다. 또한 PP보다는 시간이 덜 들어가는 것도 사실입니다.
단점
- 위에 기술한 CR의 장점은 CR의 단점이기도 합니다. 작업이 비동기로 일어나기 때문에, 리뷰 요청자는 리뷰어가 리뷰할 때까지 프로세스를 진행하지 못하는 경우가 왕왕 생길 수 있습니다.
- 또한, Face-to-face가 아닌 문서를 통해 대부분의 리뷰가 이루어지기 때문에, 서로의 의도를 정확히 이해하지 못하여 miscommunication이 일어날 수 있습니다.
- PP만큼 밀접한 협업이 일어나지 않기 때문에 지식의 동기화가 덜 일어납니다.
- 간단한 수정사항임에도 CR을 하는 경우 비효율이 발생할 수 있습니다. 따라서 무조건 모든 수정사항을 리뷰하기 보다는 요청자의 판단 하에 필요한 경우 리뷰를 요청하는 등 원칙을 정해놓는 것이 좋을 것 같습니다.
주의할 점
- 특별한 일이 없으면 리뷰어는 가급적 빨리, 늦어도 요청 후 24시간 이내에 리뷰하는 것을 원칙으로 하면 좋다고 생각합니다. 그렇지 않다면 리뷰가 계속 늘어져 머지하지 못한 PR이 여기저기 생길 것입니다.
- 코드 리뷰의 범위는 작을수록 좋은 것 같습니다. 리뷰 요청자가 한 번에 너무 많은 양의 코드를 요청하게 되면 리뷰어는 말 그대로 죽어납니다. 특히 CR을 처음 시작하는 경우 위에서 언급했듯이 comment 쓰는데도 시간이 오래 걸리기 때문에 많은 양이 아님에도 리뷰에만 7~8시간이 걸리는 것을 경험했습니다. 이러한 리뷰어의 고충을 고려하여 요청자는 가급적 작은 단위로 끊어 리뷰를 요청할 필요가 있습니다. 또 너무 많은 코드 수정 사항의 경우 github에서 다 보여주지 못하는 경우도 있었습니다.
- 리뷰어는 의견을 제시할 수 있지만, 반영 여부에 대한 최종 결정은 요청자가 하는 것이 좋다고 생각합니다. 저희는 아직까지 서로의 의견이 끝까지 상충되는 경우는 없었고, 모두 원만하게 잘 조율되었습니다. 하지만, 때로는 의견이 끝까지 좁혀지지 않는 경우도 있을 것입니다. 이러한 경우 프로세스의 빠른 진행을 위해서는 요청자가 최종 결정권을 가지면 좋을 것 같습니다.
- 온라인 리뷰를 기본으로 하되, 필요하면 오프라인 미팅을 누구라도 요청할 수 있습니다. comment를 통해서 하기에는 너무 많은 이야기거리가 있다거나 서로의 의도를 명확히 이해하지 못하는 경우에는 반드시 오프라인을 통해 이를 해소할 필요가 있습니다.
- 반면 온라인 리뷰가 없는 오프라인 리뷰는 효과가 많이 떨어지는 것 같습니다. 실제로 안드로이드와 ios간에 온라인을 거치지 않은 오프라인 리뷰 미팅을 시도했었는데, 힘든 점이 많았습니다. 플랫폼이 달라 서로 간의 이해도가 떨어지는 점이 주요 원인이었지만, 미팅 전에 소스 코드를 확인하지 않고 들어오는 경우도 대다수이기 때문이었습니다. 이렇게 되면 미팅 시에 코드 흐름을 쫓아가기에도 상당히 벅차고 다 이해하지 못하는 경우가 많기 때문에 convention 이외에는 할 이야기가 별로 없게 됩니다.
PP vs. CR
PP와 CR 모두 개발팀 전체의 수준을 한 단계 끌어올릴 수 있는 좋은 도구임에는 틀림이 없습니다. 다만 각각의 장단점을 고려하여 적절한 상황에 이용하면 금상첨화일 것입니다. 위에서 기술한 모든 내용을 종합하여 PP와 CR을 간단하게 비교해 보았습니다.
먼저 서로 가진 지식들을 tight하게 공유할 필요가 있거나, 상당히 중요한 로직을 작성하는 경우에는 PP가 더 좋은 것 같습니다. 예를 들어 기존 시스템을 완전히 뒤엎고 차세대에 버금가는 리팩토링을 한다든지, 서로 겹치지 않는 전문지식을 가진 두 사람이 지식을 공유하기 원한다든지, 팀에 새로운 분이 조인하여 업무를 익힌다든지 하는 경우에는 PP가 매우 효과적입니다.
반대로 서로의 지식이 상당히 잘 동기화가 되어 있고, 상대적으로 중요도가 떨어지는 요구사항을 구현하는 경우에는 CR로도 충분한 것 같습니다.
Wrap up
드라마앤컴퍼니 개발 그룹은 더 좋은 개발 문화를 위하여 끊임없는 노력을 게을리하지 않고 있습니다. 그 과정의 일환으로 PP와 CR에 대해 이제 막 첫걸음마를 떼었습니다. 분명 모두가 PP와 CR을 몸의 일부처럼 자연스럽게 여기는 당연한 문화로 자리잡기까지는 오랜 시간이 걸릴 것입니다. 그렇지만 지금까지 이를 경험한 모든 개발자분들이 큰 만족감을 나타내고 있어 PP와 CR 문화가 점차적으로 확산되고 정착되는데 큰 문제가 없을 것이라 생각합니다.
앞으로도 지속적인 시도와 실패로부터의 학습을 통해 더욱 더 훌륭한 모습의 개발 그룹으로 성장하는 것을 지켜봐주시길 부탁 드립니다.
Contributors
이 글은 PP와 CR에 적극적으로 참여해주시고, 가감없는 피드백을 주신 아래 분들의 도움으로 작성되었습니다.
Reference
- 카카오스토리 팀의 코드 리뷰 도입 사례 : 코드 리뷰에 대한 아주 훌륭한 글입니다. 일독을 강추드립니다.
- 깃헙으로 코드리뷰 하기
- 코드리뷰, Github로 바로 적용하기