[개발문화] 페어프로그래밍을 잘하는 방법

김준형
12 min readDec 15, 2021

--

개인적으로 한국 IT 업계에 만연한 불편함이 하나 있다면, 철학과 사상을 방법론으로 치환한 뒤에 특정 도구들(스크럼, 지라 등)을 사용하는 것을 문화라고 착각하는 것이다. 이것은 마치 운동과 식단조절은 하지 않고, 매일 체중계에 올라서며 나는 다이어트를 하고 있기 때문에 살이 빠질 것이라고 믿는 것과 같다. 페어프로그래밍도 마찬가지다. 모든 방법론들은 애초에 어떤 문제를 해결하거나 좀 더 나은 결과를 얻기 위해 탄생했다. 그러나 방법론 찬양자들은 여러 가지 이유로 그 뿌리를 도외시하고 방법론을 무조건적으로 추종한다. 그에 따른 조직적 개인적 부작용이 있더라도 애초에 문제가 있을 수 있다는 의심이 없으니 문제는 외면된다. 만약 찬양자들이 조직의 주요 결정권자들이라면 많은 사람들이 괴로워질 수 있다. 따라서 우리가 어떤 방법론을 도입하고자 할 때는 항상 왜 그 방법론이 생겼고 어떤 케이스에서 효과적으로 동작하는지를 먼저 생각해보고 그 케이스를 벗어난다면 어떤 문제가 발생할 수 있는지에 대해 고민해야 한다. 그리고 실제로 방법론을 도입했을 때 나와 내 주변에 어떤 현상들이 나타나고 있는지 면밀히 관찰하고 회고하는 것도 잊지 말아야 한다.

얼마 전 사내 개발 문화와 관련된 대화들에서 페어프로그래밍이 한 꼭지로 나왔다. 개인적으로 문화라는 큰 틀에서 페어프로그래밍이라는 주제가 연결되는 것을 좋아하지 않는다. 이유는 페어프로그래밍은 협업 도구에 가깝지 문화와 관련된 정신적 지향점을 갖고 있지 않기 때문이다.

때문에 당시 대화에서 다음과 같은 질문을 던졌다.

지금 페어프로그래밍에 대해 이야기하는 이유는 개발 문화 관점에서 하나의 중요한 프로세스로 도입하기 위함인가요, 아니면 페어프로그래밍을 하고 싶은데 익숙하지 않거나 방법을 잘 모르는 사람들을 위한 가이드라인을 만들기 위한 것인가요?

페어프로그래밍이 효과적으로 수행되기 위해서는 많은 제약 사항들이 있다. 그리고 가장 큰 착각은 같이 키보드를 놓고 타이핑 하는 것을 페어프로그래밍이라고 생각한다는 것이다. 사실 번갈아가며 키보드를 치는 것은 페어프로그래밍 전체에서 가장 마지막 단계이며 약 10% 정도의 중요성을 차지할 뿐이다. 왜 그런지를 이해하지 못한 채 기계적 프로세스로 페어프로그래밍을 하게 된다면 조직은 심각하게 비효율적인 업무 진행과 구성원들의 페어프로그래밍 공포를 경험할 수 있다.

그럼 이제 조금 더 디테일 한 내용을 이야기 해보겠다.

페어프로그래밍은 XP(Extreme Programming)의 일부로 소개되면서 이름을 알리기 시작했다. 아래는 Extreme Programming(2004, Kent Beck)이라는 책에서 소개한 페어프로그래밍의 효과이다.

● 서로 일에 집중하도록 해준다.
● 시스템을 더 좋게 다듬기 위해 무엇을 할 수 있을지 브레인스토밍한다.
● 떠오른 생각을 명료하게 다듬어 준다.
● 한 사람이 막힐 때 주도권을 다른 사람에게 넘김으로써, 짜증을 덜 나게 해준다.
● 팀에서 지키기로 한 실천방법을 서로 책임지고 지키도록 한다.

아래는 스크럼과 XP(2009, Hendrik Kniberg)라는 책에서 소개하는 내용이다.

● 짝 프로그래밍은 코드 품질을 향상시킨다.
● 짝 프로그래밍은 팀이 집중을 더 잘 할 수 있게 한다. (어떤 동료가 등 뒤에서 여러분에게 “이봐, 저 기능이 이번 스프린트에 정말 필요한거야?”라고 말하는 경우를 생각해보라.)
● 놀랍게도 짝 프로그래밍을 실제로 경험해보지도 않고서 강하게 거부하던 개발자들 중의 상당수가 한번 해 보고 나서는 금방 좋아하게 된다.
● 자주 짝을 바꾸는 것이 좋다.
● 짝 프로그래밍은 조직 내 지식 확산을 촉진시킨다. 놀라울 정도로 빠르다.
● 사람들 중에는 짝 프로그래밍이 그냥 불편한 사람이 있다. 짝 프로그래밍을 불편해 한다는 이유만으로 우수한 프로그래머를 버리지 마라.
● 코드 리뷰는 짝 프로그래밍의 좋은 대안이다.
● ‘항해자’(키보드를 가지고 있지 않은 사람) 역시 자기 컴퓨터를 가지고 있어야 한다. 개발을 하기 위해서가 아니라, 필요할 때 작은 스파이크(spike)를 해보거나 ‘운전자'(키보드를 가진 사람)가 막히게 되었을 때 관련 문서 등을 살펴보기 위해서다.
● 사람들에게 짝 프로그래밍을 강요하지 마라. 분위기를 조성하고 적당한 도구를 제공하되 그들 스스로 자신들의 속도에 맞춰 실험하게끔 하라.

우선, 책이 쓰여진지 꽤 오래되었다는 점을 감안하고 보아도, 페어프로그래밍의 효과에 대해서는 어느 정도 동의 하지만 실행 방법에는 전적으로 동의할 수는 없다. 이는 2012년 LG전자에서 처음 페어프로그래밍을 시작해서 2021년 카카오엔터프라이즈에서 페어프로그래밍이 조직 업무 방법의 일부였던 경험까지 모두 종합했을 때 내린 결론이다.

그럼 개인적으로 사용하는 페어프로그래밍 절차를 먼저 추천하고, 왜 그런 절차를 설계했는지와 페어프로그래밍의 부작용에 대해 설명해 보겠다.

먼저, 나는 아래와 같은 절차를 사용한다. LG전자의 소속 팀에서 페어프로그래밍을 도입하면서 설계한 절차이고, 매우 잘 동작했다. 그리고 지금까지도 지속적으로 사용하고 있는 모델이다.

  1. 페어프로그래밍 전의 상황과 페어프로그래밍 후 나와야 할 결과물을 정확하게 합의한다. 반드시 페어프로그래밍으로 하루 안에 끝낼 수 있는 범위여야만 한다.
  2. 페어프로그래밍에 필요한 기반 기술에 대한 이해도를 필요한 수준으로 싱크한다. 또한, 코드에 사용할 중요 단어들(도메인 용어들을 어떤 영단어로 사용할지)에 대해서도 미리 합의한다.
  3. 페어프로그래밍의 대상이 되는 패키지나 클래스의 디자인에 대해 함께 검토하고 합의한다.
  4. 코드를 막힘없이 작성하는데 필요한 기반 지식이 충분히 싱크 되었다고 합의한다면 코딩을 시작한다.
  5. 키보드와 마우스는 한쌍만 갖는다. 다만, 요즘은 IDE가 다양하기 때문에 상대방의 도구가 불편할 수 있다. 둘 모두 랩탑이라면 각자 장비를 가져와도 되지만 다른 사람이 코딩하는 순서에서는 자신의 랩탑을 닫도록 한다.
  6. 개인적으로 30분 코딩, 10분 회고+플래닝 싸이클을 선호한다. 30분 동안 코딩한 후 10분 동안 충분히 싱크되지 않았던 부분을 점검하고 디자인의 미비점이나 미처 생각하지 못했던 중요한 부분들에 대해 확인한다. 그리고 다음 코딩에서 그 부분들을 어떻게 처리할지 합의한다. 만약, 10분 안에 점검 및 합의가 불가능한 문제라면 코딩을 중단하고 1번으로 되돌아가야만 한다. 코딩을 30분으로 하는 이유는 하나의 작은 목표(함수, 클래스, 테스트 케이스 등)를 완료할 수 있으면서 운전자와 항해사 모두 집중력을 유지하는데 적절한 시간이라고 생각하기 때문이다. 추가로 운전자가 코딩을 하며 코딩하는 내용을 소리내어 설명하면 효과가 더 좋다.
  7. 페어프로그래밍 중 진행에 특별한 문제점이 감지되지 않는다면 적절한 휴식을 섞어가며 목표를 완료한다.

전체 절차를 진행할 때 가장 중요한 것은 6번의 싸이클을 돌릴 때 물흐르듯이 막힘이 없어야 한다. 코딩을 시작한 이후 키보드를 치는 시간보다 서로 의견을 나누는 시간이 더 많거나 코드를 삭제하고 재작성하는 상황이 빈번하게 발생한다면 1~4번을 제대로 하지 않은 것이므로 반드시 코딩을 중단하고 처음으로 되돌아가야 한다.

왜 위와 같은 절차를 만들었는지 이해를 돕기 위해 각 항목에 대한 설명을 조금 더 보충하겠다.

  1. 페어프로그래밍은 온전히 자신의 페이스대로 일을 이끌어가지 못하기 때문에 상당히 고단한 정신적 활동이다. 그렇기 때문에 집중력의 유지와 업무 컨택스트가 흐트러지는 것을 막기 위해 당일에 소화할 수 있는 단위로 자르는 것을 추천한다.
  2. 우리의 기술 수준은 비대칭적이며 각자의 지식 기반과 취향에 따라 함수나 클래스, 변수의 이름을 짓는 방법도 제각각이다. 둘이 함께 코딩을 할 때 이런 부분에서 논쟁으로 시간을 허비하면 안된다. 더 나쁜 케이스는 코딩 중 합의를 하지 못해 페어프로그래밍을 중단하는 것이다. 그럼 처음부터 혼자 작업하고 코드 리뷰를 받는 편이 서로 감정도 상하지 않고 진행 속도도 더 빨랐을 것이다.
  3. 2번과 같은 맥락이다. 페어프로그래밍의 최종 단계인 코딩을 시작하기 전에 최대한 논쟁 거리를 제거해야만 한다.
  4. 지식 수준과 구현에 필요한 내용을 충분히 합의하지 않는다면 후술하게 될 부작용이 나타나게 된다. 이 과정을 제대로 마치지 못했을 때 어떤 상황이 발생하는지는 따로 설명하겠다.
  5. 운전자는 코드 작성에 집중하고 항해사는 합의된 내용을 지키고 있는지 코드에 버그가 없는지를 확인해야 하기 때문에 코딩 중 다른 문서를 보거나 spike를 할 여유 따위는 없다. 타인이 지켜보는 코드를 짜는 운전자와 타인의 코드를 실시간으로 읽으며 점검하는 항해사 모두 매우 큰 집중력을 필요로 한다. 특히, 항해사는 절대 딴짓하면 안된다.
  6. 시간 배분은 상황에 맞게 조절하면 된다. 막힘없이 코딩이 진행되고 있는지 계속 신경을 쓰고, 흐름이 계속 끊긴다면 코딩을 중단하고 상황을 점검해야 한다. 흐름이 끊긴다는 것은 충분히 준비되지 않았다는 것이다.
  7. 만약, 1~4의 활동으로 충분한 준비가 되었고 코딩 컨벤션이나 여러 가지 그라운드 룰이 잘 되어 있다면 10분은 괜찮은 휴식 시간이 될 것이다. 그렇지 않다면 별도의 휴식 시간을 갖도록 하자.

이제 페어프로그래밍에는 어떤 종류의 부작용들이 존재하고 있고, 왜 페어프로그래밍을 사용하는데 주의를 기울여야 하는지 의견을 적겠다.

  1. 운전자는 열심히 코딩하지만, 항해사는 뭐가 진행되고 있는지 모르고 멍때리고 있다. 이와 같은 부작용은 두 사람의 작업 이해도 차이가 매우 클 때 나타난다. 주니어와 시니어 같이 기술적 경험 차이 때문일 수도 있고, 기존 구성원과 신규 입사자와 같이 도메인 이해도 차이 때문일 수도 있다. 어쨌든 문제의 핵심은 페어프로그래밍을 하면 자연스럽게 지식이 전달되고 상대방의 이해도가 올라갈 것이라고 착각하는데 있다. 하지만, 상황은 전혀 그렇지 않다. 항해사의 임무는 운전자의 실수를 보완하는 것이지 운전자의 코딩을 통해 학습하는 것이 아니다. 항해사가 운전자의 코딩을 실시간으로 따라갈 수 없다고 해서 빈번하게 코딩을 중단시키고 하나하나 물어볼 수는 없다. 그래서는 운전자가 코드를 몇 줄 짜지도 못한다. 결국 항해사는 자신의 존재 이유를 찾지 못하고 영혼이 탈출해 버린다. 운전자가 짜는 코드를 이해하지 못하는데 코드 품질을 더 향상시킬 수 있다는 기대는 비현실적이며, 항해사가 운전자로 역할을 바꾸게 된다면 자신이 이해하지 못한 코드를 이어 받아 계속 구현을 진행할 수 있을리가 없다.
  2. 항해사가 처음부터 끝까지 지시를 내리며 운전자는 받아 적는 타이핑 머신이 되어 있다. 이 상황은 1번에서 운전자와 항해사가 역할을 바꾸었을 때 나타난다. 처음에는 룰에 따라 운전자가 코딩을 하고 항해사는 서포트를 하려고 하지만, 항해사가 보기에는 시작부터 문제들이 보인다. 그럼 하나하나 지적하게 되고, 운전자는 위축되고 자신이 바보처럼 보이고 있다는 공포를 느낀다. 얼마 지나지 않아 항해사는 운전자가 스스로 코딩할 상황이 아니라고 판단하고 한줄한줄 작성할 코드를 말해준다. 그리고 운전자는 그 코드를 받아 적는다. 평범한 뇌는 타인의 코드를 정확하게 받아 적는 것과 그 코드를 곧바로 이해하는 두 가지 정신적 활동을 동시에 하기 힘들다. 특히 위축되고 불편함이나 공포심을 느끼는 상태라면 더더욱 그렇다. 이 상황에서 지식의 확산이 이루어질 것이라는 기대는 부질없다. 결국 항해사가 혼자 하면 될 것을 운전자의 귀중한 시간을 낭비하고 부정적 감정만 심어주는 결과를 얻을 수 있다.
  3. 결과물이 나오지 않았는데 페어가 나머지는 알아서 마무리하라며 페어프로그래밍을 마무리해 버린다. 이 경우는 정확한 설계와 결과에 대한 합의가 없이 페어프로그래밍을 시작했을 때 발생한다. 우리는 항상 대충 머리를 굴려보면 이렇게 하면 될 것 같다는 상이 떠오른다. 하지만, 간과하는 것은 대부분 실제로 실행해보면 디테일이 상당히 다르다는 점이다. 이 상황은 대부분의 경우 해당 이슈 티켓에 오너가 아닌 사람(보통 시니어)이 주니어의 업무 진행을 답답하게 느껴 페어프로그래밍을 제안한 후 실제로 해보니 옆에서 봤던 것 만큼 간단한 문제가 아님을 알고 황급히 손을 떼게 될 때 자주 발생한다. 이 상황이 반복되면 페어프로그래밍 요청자는 신뢰를 잃게 되고, 상대방은 페어프로그래밍을 자신의 일을 방해하는 도구로 불신하게 된다. 페어프로그래밍에서 설계를 합의해야 하는 이유가 이와 같은 상황을 방지하기 위함이다.
  4. 강제로 이슈티켓과 페어프로그래밍을 묶어버리면 일을 하는 사람만 하거나 일이 끝나지 않는다. 이는 페어프로그래밍 중 가장 잘못된 상황이라고 본다. 상황과 목적에 맞춰 써야하는 도구를 프로세스의 필수 요소로 강제해 버리면 업무 진행의 유연성을 잃게 되기 때문이다. 일을 완수해야 하는 책임이 둘로 나뉘게 되면 새로운 일에만 흥미를 느끼는 사람이 다른 사람에게 일을 미루거나 둘 모두 서로 알아서 하겠지라는 안일한 생각으로 결국 일이 좌초하는 상황이 발생할 수 있다. 우리는 항상 모든 일에는 한 명의 책임자가 있어야 하며 그 일에 대해서는 전적으로 책임자의 권한을 존중해야 한다는 것을 명심해야 한다. 페어프로그래밍이 문화와 프로세스의 일부로 강제되면 책임의 소재가 모호해지거나 책임자의 권한을 함부로 침해하게 될 수 있다.

페어프로그래밍 도입 후 위와 같은 문제 상황들이 빈번하게 발생한다면 페어프로그래밍을 제대로 사용하고 있지 않다고 생각해야 한다. 우리가 페어프로그래밍을 하는 이유는 조직과 업무에 이익을 얻고자 함이지 개개인의 업무를 방해하고 정신적 괴로움에 빠뜨리려는 것이 아니기 때문이다.

내 경험으로 페어프로그래밍이 가장 잘 작동했던 기억들은 트레이닝의 성격이 강했다. 당시 나는 언어와 OOP, CS에 능숙했고, 상대는 도메인에서 오래 일을 한 분이었다. 코딩 단계를 준비하며 합의를 위해 나누는 대화들은 서로의 기술과 도메인 지식을 교환하기에 더 없이 좋은 기회이다. 또한, 어떤 의식의 흐름으로 코드를 작성하고 있는지 운전자에게 항해사에게 설명하는 것은 상대방의 사고 방식을 배우기에 매우 좋은 기회이다. 그 끝에서 서로 키보드를 토스하며 물흐르듯이 코드를 작성해 함께 동작하는 결과물을 완성하는 경험은 상당한 쾌감을 안겨주었다. 나는 도메인의 지식을 얻은 후 그것을 코드라는 결과물로 완성하는 하나의 흐름을 경험할 수 있었다. 그리고 상대방은 회고에서 내가 오픈소스 라이브러리를 문서 없이 이해하고 사용하는 모습에서 인터페이스와 추상화라는 것에 대한 새로운 레벨의 깨달음이 있었다고 밝혔다.

이와 같이 페어프로그래밍은 잘 사용하면 상당히 긍정적인 협업 경험을 만들 수 있지만, 정확한 이해를 바탕으로 수행하지 않으면 원하는 대로 동작하지 않는다. 그래서인지 주변을 둘러보면 빅테크를 포함한 IT 인더스트리에서 페어프로그래밍은 코드리뷰나 유닛테스트보다 도입이나 사용이 활발하지 않다. 페어프로그래밍에서 얻고자 하는 가치는 크게 코드 품질의 향상과 지식 및 경험의 교환이라는 측면이 있는데, 코드리뷰와 유닛테스트, 인수테스트, 정적분석 등으로 코드 품질 향상을 꾀할 수 있고 각종 문서 공유와 커뮤니케이션 개선을 통해 지식 및 경험의 교환이라는 목적을 달성할 수 있기 때문으로 추측한다.

따라서 페어프로그래밍에 관심이 있다면, 조직 단위의 도입이나 프로세스에 편입을 시도하기 전에 이제까지 설명한 내용들을 숙지하고 시도해보면서 내게 잘 맞는 도구인지 그 가치를 스스로 평가해 보기를 바란다.

--

--