지속 가능한 SW 개발을 위한 코드리뷰 세미나 정리 및 후기

코드리뷰

이 글은 우아한 테크 세미나에서 강연을 하신 백명석님의 지속 가능한 SW 개발을 위한 코드 리뷰에 대한 정리 및 후기입니다. 참고 링크: https://www.youtube.com/watch?v=ssDMIcPBqUE

계기

이 세미나를 듣게 된 계기는 최근에 같은 학생들끼리 프로젝트를 하고 있는데 각자 자기가 맡은 부분만 관심을 가지고 개발해 진행하다 보니 서로의 코드에 대한 피드백이나 리뷰는 없고 일방적으로 자기 스타일 대로만 개발코드를 짜고 합치고 반복하다보니 뭔가 빠진 것 같고 이게 맞는건가?? 하는 불안한 생각이 들었다. 분명 같이 하고 있는데 왜 혼자하는 것 같은 공허한 느낌도 들었던 것 같다..

거기다가 중간에 문제가 생기면 그 문제에 관련된 개발을 한 사람이 다 책임을 지고 고치는데 그 사람만 문제에 대해 관심을 가지고 나머지는 무관심했던 것 같다. 듣고나서 생각해보니깐 정말 외롭고 너무했던것 같은 생각이 들었다ㅜㅜ..

만들 때 리팩터링과 클린코드, 코드리뷰에 대해 관심은 있었지만 자세하게 알지 못했고 내가 다른 사람의 코드를 판별할 수준이 되나?? 라는 생각을 가지고 있어서 프로젝트를 진행할때 적용을 못했던 것 같다.

하지만 어느 정도 진행을 하면서 개발에 대해 자신감이 조금 생기고 프로젝트가 안정화되어 여유가 조금 생기니 제일 먼저 리팩터링과 코드리뷰를 공부하여 적용하고 싶은 생각이 들었던 것 같다. 아마 이대로 가다가는 나중에 터질 것 같다는 직감이 아니였을까 싶다.

그렇게 세미나를 접하게 되었고, 듣고 나니 내가 가려웠던 부분을 시원하게 긁어주었고 자신감을 얻은 것 같다. 이 글을 어서 마무리하고 정리한 세미나 내용을 프로젝트 팀원들에게 빨리 전해서 같이 공부하고 적용하고 싶다. 자 어서 세미나 내용으로 가보자.

세미나 정리

시작전 이런 말씀을 하셨다. 개발은 나 혼자 성장하는게 아니라 다른 사람까지 성장 시키는 일이다. 자기 혼자 잘할 수 있지만 그 결과가 작다. 하지만 나보다 부족한사람, 더 잘하는 사람, 유사한 사람과 함께 협력해서 한다면 더 큰 결과물을 낼 수 있다고 한다. 그래서 공유를 통해서 협력을 이뤄내고 결과를 극대화 할 수 있는 방법들 중 하나인 코드리뷰를 준비하게 되었다고 하셨다. (그 동안의 나를 반성하게 되었다..)

왜 코드 리뷰를 해야하나?

우리가 살고있는 시대는 현재 소프트웨어에 의해 운영되는 제품과 서비들의 영역이 늘어나고 있고 변동성의 시대로 변화의 속도가 빠르고 다양하게 전개될 것이라고 한다. 또 Global GDP에서 Tech의 비율은 2020년에 5%에서 2030년 10%로 증가할 것으로 보이는데 주목할 것은 나머지 90%. 즉, Digtal Transform은 이제 시작인 것이다. 그렇기 떄문에 비즈니스 성공을 위한 개발 조직의 성능(생산성)이 중요해졌다.

그림을 보면 좋은 디자인은 개발 생산성이 꾸준하게 느는걸 볼 수 있다.(좋은 디자인이 나오려면 코드 리뷰나 어떤 좋은 수단이 필요)


SW 공학의 특성

  • 공학 활동의 최종 목적
    • 빌드 할 수 있는 어떤 종류의 재생산 가능한(Reproducible) 문서
  • SW 공학의 설계와 빌드
    • 설계 = 완전한 소스 코드
    • SW 빌드 = 컴파일
  • 좋은 설계 ~= 클린코드
  • SW 엔지니어: 설계를 잘하는 사람 -> 코드를 잘 작성하는 사람
  • 클린 코드의 중요성
    • SW의 진정한 비용 ~= 유지보수(전체의 80% 이상)
    • 한번 작성한 코드는 10번 이상 읽음. 작성 보다 이해에 10배의 노력 소요
    • 90% 이상의 시간을 어떤 코드를 이해하는데 사용함


목적

  • 주목적: 품질 문제 검수(버그, 장애)
  • 더 나은 코드 품질: 아키텍처 속성 개선을 위한 코드 개선(향후 변경 비용 개선)
  • 학습 및 지식 전달: 코드 해결책 등과 관련된 지식 공유에 기여
    • 공유(주고 받는 학습)를 통한 역량 증대 및 성장
      • 대개의 경우 리뷰어들도 리뷰 과정에서 지식을 얻게 됨(하드스킬, 소프트스킬)
    • 동기 부여(잘하는 사람이 하는걸 보면 대부분 사람은 잘하고 싶은 마음이 생김)
  • 상호 책임감 증대
    • 집단 코드 오너십 및 결속 증대
    • 내가 하고 있는 일에 관심을 가져주는 것
    • 팀에서 일어나는 일 공유. 내 동료는 무엇을 하나? 팀웍
  • 설계 개선 제안(좋은 사례 공유, 부족한 부분에 대해 의견을 물어 볼 수 있음)
  • 개발 문화 개선

듣다가 상호 책임감 증대에서 진짜 공감이 되었던 것 같다.. 처음에도 말했듯이 문제가 생기게 되면 관련된 사람에게만 잘못을 묻고 하는 것은 개개인뿐만 아니라 팀에게도 좋지 않은 것 같다.

팀원이 다같이 코드를 검수하는 시간을 가졌다면 내가 작성한 코드가 아니어도 팀원의 일원으로 책임감이 생기게 될꺼고 그렇게 되면 자동으로 집단 코드 오너십 및 결속이 증대되는 것이다. 이렇게 팀웍이 쌓여서 팀이 한층 더 성장하지 않나 싶다.

코드 리뷰의 절차

  • 저자(Author)
    • 코드 작성, 리뷰 요청
  • 리뷰어
    • 코드를 읽고 머지 가능한가 결정
  • 변경 내역(Cahnge List, PR)
    • 리뷰 시작 전에 작성
    • 저자가 머지를 원하는 소스 코드에 대한 일련의 변경(잘한 것, 아쉬운 것, 눈여겨 볼 것)에 대해 기술

좋은 Pull Request 예

왜 코드 리뷰가 어려운가? 기본적으로 저자는 본인 생각에 멋지다고 생각하는 PR을 보내고 리뷰어는 왜 멋지지 않은지에 대한 장황한 이유를 작성하기 때문에 여기서 갈등이 생기게 된다. 저자나 리뷰어나 내가 좀 틀릴 수 있구나 저 사람이 맞을 수 있구나 이런 마음가짐으로 접근해야지 내가 너보다 훌륭한 개발자야 라는 마음으로 접근하면 서로에게 문제가 된다. 그리고 코드에 대한 비판은 그때 작성한 코드에 대한 거지 자신에 대한 비판이 아니므로 분리해서 생각해야 한다.

코드리뷰는 지식을 공유하는 기회이자 공유를 통해 서로의 지식/경험을 나누며 상호 학습을 통한 역량 증대 수단이다. 그러므로 코드 토의를 개인적 공격으로 받아들이면 물거품이 된다. 생각을 글로 전달하는 것은 매우 어렵다. 음성 톤, 표정의 부재로 오해의 위험성이 크다. 그러므로 피드백을 할때 조심스럽게 표현하는 것이 매우 중요하다!

효율적인 PR 방법

지루한 작업은 컴퓨터로 처리

  • 코드를 읽는 것은 인지적 부담이 되는 고수준의 집중이 요구되는 작업
    • 컴퓨터가 할 수 있는 일에 이런 노력을 낭비하지 말라
    • 심지어 기계가 더 잘 할 수 있는 일에(예를들어 build, test, merge conflict 찾기 등등..)
  • Formatting Tool
    • 공백, 들여쓰기 오류 등
    • 별도의 커밋/PR로 분리. 리뷰 불필요를 기술해서 리뷰를 생략할 수 있도록


스타일 가이드를 통해 스타일 논쟁을 해소

  • 스타일에 대한 논쟁은 리뷰에서 시간 낭비
    1. 좋은 스타일 가져다 써라!
    2. 아니면 쓰고있는 스타일을 점진적으로 개선
    3. 아니면 두개를 하이브리드로


PR을 올릴 때 주석 달기

  • PR을 저자가 먼저 읽어보고 -> 리뷰어들을 위한 설명을 커멘트로 남겨서 -> 리뷰어들의 시간을 절약할 수 있게 하라


리뷰어에 모두를 포함하라

  • 많은 사람들이 볼 수록 버그를 더 잘 찾아낼 수 있다.
  • 많은 사람들이 본다는 것을 알면 사람들은 대개 더 잘 하려는 경향이 있다.(코드 / PR 작성)


의미 있는 커밋으로 분리

  • 작게 나눠서 커밋을 하면 보는사람이 편함

효율적인 리뷰 방법

리뷰는 즉시 시작

  • 코드 리뷰를 높은 우선순위로
    • 저자는 리뷰 종료 될 때까지 대기함
  • 리뷰를 바로 시작하면 선순환됨
    • 코드를 읽고 피드백을 줄 떄는 시간을 가지고 진행해도 되지만 시작은 바로 해라
    • 이상적으로는 수분 내에
  • 리뷰 라운드의 최대 시간은 하루
    • 우선순위 높은 업무로 1일 내 불가하면 다른 리뷰어 지정
    • 월 1회 이상 재지정을 해야한다면 속도를 줄여서 건강한 개발 관습(Practice)을 유지할 수 있어야 함

남의 것을 리뷰하는 것에 대한 것을 조직내에서 인정해주지 않기 때문에 그거에 대한 따로 시간을 내기 힘든 것이다. 그래서 리뷰를 하는 것에 대한 문제라기 보다는 조직적인 문제라 볼 수 있다. 어떻게든 보장되도록 조직적으로 접근할 필요가 있다.


그리고 Pull Requests와 Pair Programming 중 어느게 더 좋은지 논쟁이 있는데 두 가지는 각각의 트레이드오프가 있다. Pull Requests 같은 경우 지연시간이 있고 Pair Programming 같은 경우는 바로바로 하니깐 지연시간(Latency)이 없다. 근데 처리량(Throughput)의 경우 Pull Requests가 여러명이서 하기 때문에 Pair Programming 보다 좋다고 할 수 있다.

또한 팀의 성향에 따라 달라지는데 팀원들이 좀 내성적이거나 사색적인 경우는 Pull Request가 더 어울리고 팀원이 외향적이거나 친밀한 개인적 상호작용이 있는 경우에는 Pair Programming이 더 좋다고 할 수 있다. 하지만 절대 어느 것이 더 좋다는 답은 없고 아니면 섞어하는 앙상블 방식도 있다.


고수준으로 시작, 저수준으로 내려가라

  • 리뷰 라운드에서 많은 의견을 남길 수록, 저자가 당황할 위험 커짐
  • 하나의 라운드에 20~50개 정도의 의견은 위험의 시작
  • 초기 라운드에서는 고수준 피드백으로 제한
    • 버그, 장애, 성능, 보안 등
  • 고수준의 피드백이 처리된 후에 저수준 이슈를 처리
    • (선택적인) 설계 개선


예제 코드 제공에 관대해라

  • 저자를 기분 좋게 하기 위한 방법
    • 리뷰 중에 선물 주기(코드 예제)
  • 너무 긴 예제는 관대한 것이 아니라 억압적으로 보임
  • 라운드당 2~3개의 코드 예제로 제한
    • 모든 PR에 예제를 제공하면 저자가 코드를 작성할 수 없다고 무시하는 것 같음


리뷰의 범위를 존중하라

  • PR에 포함되지 않은 라인은 리뷰 범위가 아님


태그를 활용

  • [Nit]
    • ‘고치면 좋지만 아니어도 그만’을 의미
    • 그래도 보통 고침
    • 리뷰어는 항상 더 개선할 수 있는 의견을 자유롭게 남길 수 있어야 함
    • 중요치 않다면 “Nit”를 태그로 남겨서 저자가 무시할 수 있도록 할 수 있음
    • 교육적인 목적, 지속적으로 기술을 연마하는 것을 돕는 목적
    • 예) nit: null 대신 Optional을 쓰면 어떨까요?


한두 등급만 코드 레벨을 올리는 것을 목표로

  • D 등급의 PR을 받으면 저자가 C나 B 등급을 받도록 도와라 (한번에 다 받아들여서 갑자기 A등급이 될 수는 없음)
    • Letter Grade
  • 완전하지는 않아도 충분히 좋은 코드가 되도록

피드백 방법

절대 “너”라고 하지 마라

  • 리뷰의 핵심
    • “무엇이 코드를 나아지게 하는가”
    • “누가 그런 아이디어(잘못)를 냈는지”가 아님
  • 저자의 방어 유발을 최소화하는 방법으로 피드백
    • 비판의 대상은 코드. 저자가 아님
  • “너”만 빼라
    • I Message 대화법: 행동 - 결과 - 감정 (예를들어 너의 어떤 행동이 결과가 이렇게되서 내 기분이 어떻다.)
  • ~하는 것을 제안합니다. ~하는게 어떨까요 ? <- 오픈 커뮤니케이션
    • 물어보면 대답을 한다. 제안 한 것을 안한다고 대답하기도 편하고


건설적인 피드백을 하라

  • 동료들 간의 코드 리뷰
    • 경쟁 유발 시키는 것이 아닌 팀의 생산성을 높이려는 것
  • 코드 리뷰를 자신의 코드에 대한 비판이 아니라 학습의 과정으로 인지하면 전체적으로 프로젝트의 성공에 기여함
  • 건설적인 피드백은 개발자들이 그들의 실수에서 배우고 역량을 증대하도록 동기부여함
  • 건설적인 피드백을 못하겠으면 차라리 아무 말도 안하는 것이 오히려 나음


진정한 칭찬을 해라

  • 대부분의 리뷰어가 잘못된 부분에만 집중하는데 하지만 리뷰는 긍정적 행위 강화를 위한 값진 기회이기도 하다.
  • PR에서 좋은 변경이 있을 때마다
    • “오 이런 API가 있나요. 정말 유용해요”
    • “정말 좋은 해결책이네요.”
  • 저자가 주니어 혹은 신규 입사자라면 리뷰에 매우 민감하고 방어적일 수 있음
  • 진심어린 칭찬은 리뷰어가 잔인한 감시자가 아니라 도와주려는 팀동료라는 것을 보여서 이런 긴장감을 낮춘다.


피드백은 명령이 아니라 요청으로 표현해라

  • 우리는 일상에서 동료에게 명령하지 않는다
  • 하지만 리뷰에서는 강압적인 명령이 종종 발견되고 한다.
    • ex. 이 클래스를 별도의 파일로 분리하라 -> 이 클래스를 별도의 파일로 분리할 수 있을까요?


의견이 아니라 원칙에 기반하여 피드백하라

  • 저자에게 의견을 줄 때는 “제안하는 변경”과 “변경의 이유”를 모두 설명하라
    • ex. 이 클래스를 2개로 분리해야 해요 -> 지금 이 클래스는 파일 다운르도와 파싱의 2가지 책임을 가지고 있어요. 다운로더와 파서 2개의 클래스로 분리하여 SRP를 준수하는 것이 어떨까요 ?
  • SW는 과학인 동시에 예술
    • 항상 원칙에 기반하여 정확히 뭐가 잘못 되었는지 언급할 수는 없다.
    • 단지 그냥 보기 싫거나 직관적이지 않을 수 있다
    • 무엇을 할 수 있을지 객관적으로 설명하라
    • ex. 이 코드는 혼란스럽네요(너?) -> 나는 이 코드를 이해하기 어렵네요 (I Message) 라고 말하게 되면 왜 이해하기 어려울까 고민할 수도 있고 물어 볼수도 있다.


반복적인 패턴에 대해서 피드백을 제한하라

  • 저자의 실수가 동일한 패턴임을 식별 했다면 모든 경우를 언급하지는 말라
  • 동일 패턴에 대해서 2~3개 정도의 예를 언급하라
  • 그 이상은 저자에게 개별 사례가 아니라 패턴에 대해서 수정을 요구하라

교착상태 시

교착 상태를 적극적으로 처리해라

  • 교착 상태로 향하는지 나타내는 표식
    • 토론의 톤이 점차 팽팽해지고 공격적으로 됨
    • 라운드당 커멘트가 줄어들지 않는 경향을 보임
    • 너무 많은 커멘트에 저항이 보임
  • 코드 리뷰의 최악의 결과는 교착상태(Stalemate)
    • 커멘트를 반영하지 않으니 승인 거부
    • 저자는 커멘트 반영을 거부
  • 만나서 애기하라
    • 화상 혹은 만나서 논의(특히 복잡한 리뷰)
    • 텍스트 기반 의사소통은 상대가 인간이라는 것을 잊게 함
  • 인정하거나 Escalate하라
    • 교착상태가 길어지면 관계가 나빠짐
    • 그냥 승인하는 비용(Agree to disagree - 갈등 해결책)
    • 저수준 코드를 무심코 승인하면 SW 품질이 낮아질 수 있음
    • 동료와 너무 다퉈서 함께 일하지 않게 된다면 고수준의 품질을 얻을 기회가 사라짐(적당하면 타협하자)
  • 인정이 불가한 경우
    • 저자에게 논의를 팀장이나 테크 리더에게 Escalation
    • 다른 리뷰어에게 할당
  • 교착상태로 부터 회복
    • 상황을 관리자와 논의하라
    • 휴식을 가져라. 가능하다면 안정될 때까지 PR을 서로 보내지 마라
    • 갈등 해결책을 학습하라
  • 설계 리뷰를 고려하라
    • 코드 리뷰 때 설계 리뷰 때 논의되었어야 할 사항을 논쟁하는가?
    • 설계 리뷰는 있었나?
  • 아주 심각하지 않다면
    • 그냥 인정하고 좋은 관계로 동료와의 협업을 지속해라
    • Agree to disagree

코드 리뷰를 하는 아주 재밌는 방법

PR을 작성한 사람과 짝 프로그래밍을 하며 어떻게 고치는 게 좋은지 보여주고 다시 Revert한 다음에 PR을 작성한 사람이 스스로 개선할 수 있도록 기회를 준다. 이렇게 하면 짝이 20분 걸린 거를 PR을 작성한 사람은 2시간이 걸릴 수도 있지만 그렇게 해야 스스로 하는 법을 배우고 적용할 수 있게 된다.

이렇게 할 때 제일 중요한 건 결정은 저자가 하는 것이다. 우리는 “완벽한 설계”가 아니라 “할 수 있는 최고의 설계”를 추구하는 것이다. 그렇기 때문에 팀 정신을 유지하기 위해 불완전한 해결책을 받아들여야 한다. 모든 설계 결함이 항상 실제로 문제가 되지는 않는다. 그리고 코드 리뷰의 목적은 비난이 아니라 배움이기 때문에 전혀 불편할 필요가 없다. 저자만 배우는 게 아니라 리뷰어들도 배우는 것이다.

리뷰하려는 코드가 그냥 나쁠 때가 있을 수도 있다. 하지만 저자가 그날 어떤 일이 있었을지 모른다. 그렇기 때문에 비난하기 보다는 “XXX님. 이 코드 샘플을 당신의 이력서에 추가할까요?” 라는 농담을 던질 수 있는 동료가 되도록 하자. 신규 입사자, 경험이 부족한 팀원의 코드를 리뷰하면서 이런 상황을 만났다면 좀 더 안내하는 가르침으로 전환하자.


마무리

이 뒤 세미나에는 Appendix로 코드 리뷰 문화 정착의 어려움/극복 방법, 코드 리뷰 효과, 코드리뷰를 잘 하기 위해 필요한 기술들, 자주 하는 QNA등 유익한 내용들이 더 있다. 더 관심있는 사람들은 https://www.youtube.com/watch?v=ssDMIcPBqUE 링크로 가서 1:22:36초 부터 시청하면 된다.

처음으로 이렇게 긴 개발 관련 세미나를 듣고 정리를 해봤는데 정말 도움이 많이 된 것 같다. 유익할 뿐 아니라 정말 재미있어서 시간이 순식간에 간 것 같다. 왜 이제 알았는지…ㅜ 앞으로 자주 세미나를 찾아보고 들을 것 같다. 상황이 되면 온라인 말고 오프라인 세미나도 참석하고 싶다. 사실 위에 정리한 양이 워낙 많아서 후기보단 정리에 더 가까운 거 같다ㅋㅋㅋ. 저것도 진짜 전해주고 싶은 내용만 골라 정리한 것이라서 직접 세미나를 보는 걸 추천한다! 더 유익하고 자세한 내용이 많다고 자신할 수 있다.

이 글을 적으면서 빨리 프로젝트 팀원들에게 전하고 싶은 급한 마음에 글이 잘 적힌지 모르겠다. 마지막으로 이렇게 좋은 강연을 해주신 백명석님께 감사드리고 매끄러운 진행을 해주신 JADE님께도 감사하다고 전하고 싶다!

*오타가 있거나 피드백 주실 부분이 있으면 편하게 말씀해 주세요.


© 2022. All rights reserved.

Powered by 애송이