2. 2
Contents
● 코드리뷰란 ?
● 왜 코드리뷰가 어려운가 ?
● 8가지 기법들
● 나의 최악의 코드리뷰 사례
● 중재
● 7가지 기법들
● 나의 최악의 코드리뷰 사례 revisited
● References
3. 3
코드리뷰란 ?
● 저자(Author)
- 코드를 작성하고 리뷰를 요청
● 리뷰어(Reviewer)
- 코드를 읽고
- 머지 가능한지 결정
● Changelist
- 리뷰 시작 전에 작성.
- 저자가 머지를 원하는 소스 코드에 대한 일
련의 변경(잘 한 것, 아쉬운 것, 눈여겨 볼 것)
● CR(Code Review) happen in
rounds
- 저자와 리뷰어 간의 완결된 Round-trip
- 저자는 변경을 보내고
- 리뷰어는 변경에 대해서 글로써 응답
- 각 CR은 하나 이상의 라운드를 가짐
- 리뷰어가 승인함으로써 종료 -
LGTM(Looks good to me)
1. change list
2. written
feedback
3. approval
4. merge
4. 4
왜 코드리뷰가 어려운가 ?
● 저자
- 본인 생각에 멋지다고 생각하는 Changelist를 보낸다
● 리뷰어
- 왜 멋지지 않은지에 대한 장황한 이유를 작성
● “자신의 기술 레벨을 지나치게 과대평가한 비행기 조종사들은 모두 죽었다”
- “In aviation, for example, people who greatly overestimate their level of skills are all dead”
● Code에 대한 비판을 자신이 무능한 프로그래머라고 이해한다.
- 게다가 상대가 직책자이면...
● Code Review는
- 지식 / 공학적 결정을 공유 하는 기회. 공유(잘 한 것, 아쉬운 것)를 통해 서로의 지식/경험을 나누며 역량 증대 수단
- 저자가 코드에 대한 토의를 개인적 공격으로 받아들이면 물거품
● 생각을 글로 전달하는 것에 대한 어려움
- 오해의 위험이 크다
- 음성 톤, 표정의 부재
● 피드백을 조심스럽게 표현하는 것이 더 중요
- “You forgot to close the file handle” 를
- “I can’t believe you forgot to close the file handle ! You’re such an idiot” 로 받아들임
5. 5
기법들
1. 지루한 부분은 컴퓨터로 처리
2. 스타일 가이드를 통해 스타일 논쟁을 해소
3. 리뷰는 즉시 시작하라
4. 고 수준으로 시작해서 저 수준으로 내려가라
5. 예제 코드 제공에 관대해라
6. 절대 “너”라고 하지 마라
7. 피드백으로 명령이 아니라 요청으로 표현해라
8. 의견이 아니라 원칙에 기반하여 피드백하라
6. 6
1. 지루한 부분은 컴퓨터로 처리
● 코드를 읽는 것은 인지적으로 부담되는 고 수준의 집중이 요구되
는 작업
- 컴퓨터가 할 수 있는 일에 이런 노력을 낭비하지 말라(심지어 기계가 더 잘 할 수 있는
일에)
● Formatting Tool
- 공백, 들여쓰기 오류 등
- 별도의 커밋으로 처리해서 리뷰를 생략할 수 있도록 해라
● Unused imports or variables
● Build / Test Passes
● Merge Conflict
● Locate Duplicates를 파일 단위로 수행하여 중복 제거
● 이러한 자동화는
- 리뷰어가 리뷰어로써 보다 의미있는 기여를 할 수 있도록 하고,
- 저자는 사소한 실수를 발견할 수 있도록 한다.
7. 7
2. 스타일 가이드를 통해 스타일 논쟁을 해소
● 스타일에 대한 논쟁은 리뷰에서 시간 낭비
- Option1: Adopt an existing style guide
- Option2: Create your own style guide incrementally
- Option3: The Hybrid approach
8. 8
3. 리뷰는 즉시 시작하라
● CR를 높은 우선순위로 다뤄라
- 동료가 Changelist를 보내는 것은 당신의 리뷰가 종료될 때까지 그가 대기(Blocked)
함을 의미
- 코드를 읽고 피드백을 줄 때는 시간을 가지고 진행해도 되지만 시작은 바로 해라. 이
상적으로는 수분 내에
● 리뷰를 바로 시작하면 선순환됨
- Changelist의 Size와 Complexity가 중요.
- 작고, 범위가 좋은 Changelist —>
- 쉽고 상쾌하기 리뷰하기 좋음 —>
- 빠르게 리뷰 수행
- 위의 선순환이 지속됨
● 1,000 LOC Feature(200 LOC 리뷰에 2시간 소요 가정)
- 200 LOC로 Feature를 분리해서 PR -> 1~2일에 리뷰 완료가 바람직
- LOC에 무관하게 1일 소요된다면 Review에 1주일 소요(200 LOC/D)
- 1주일 동안 대기 원치 않으므로 500~600 LOC를 보내게 됨
- 리뷰 코스트 증가. 품질 낮은 피드백 유발(200 LOC보다 600 LOC가 집중하기 어
려우므로)
9. 9
3. 리뷰는 즉시 시작하라
● 리뷰 라운드의 최대 시간은 하루
- 우선순위 높은 업무로 1일 내 불가하면 다른 리뷰어를 지정
- 월 1회 이상 재지정을 해야한다면 속도를 줄여서 건강한 개발 Practices를 유지할 수
있어야함
10. 10
4. 고 수준으로 시작해서 저 수준으로 내려가라
● 리뷰 라운드에서 더 많은 의견을 남길 수록, 저자가 당황할 위험
커짐
- 하나의 라운드에 20~50개 정도의 의견은 위험의 시작
- 초기 라운드에서는 고 수준 피드백으로 제한
- 인터페이스 클래스의 재설계, 복합한 함수의 분리 등
- 고 수준의 피드백이 처리된 후에 저 수준 이슈를 처리
- 변수명 변경, 주석을 명확하게 하는 것 등
11. 11
5. 예제 코드 제공에 관대해라
● 저자를 기분 좋게 하기 위한 방법
- 리뷰 중에 선물 주기(코드 예제)
- “list comprehension으로 간단하겨 할 수 있지 않을까요 ?”
- list comprehension을 모른다면 20분을 헤매야
● 예제가 너무 길다면 관대한 것이 아니라 억업적으로 보임
● 라운드당 2~3개의 코드 예제로 제한
- 모든 Changelist에 예제를 제공하면 저자가 코드를 작성할 수 없다고 생각한다는 신
호
12. 12
6. 절대 “너”라고 하지 마라
● 리뷰의 결정은 “무엇이 코드를 나아지게 하는가”이지 “누가 그런
아이디어를 냈는지”가 아니다.
● 저자는 Changelist에 막대한 노력을 들였고, 자신의 일을 자랑스
럽게 생각한다.
- 비판에 대한 그들의 자연적 반응은 방어/보호하려는 것
● 저자의 방어 유발을 최소화하는 방법으로 피드백하라
- 비판의 대상이 코드이지 저자가 아님을 명확히 하라
- 저자가 “너”라는 단어를 보면 주의가 코드에서 자신들로 바뀜
13. 13
6. 절대 “너”라고 하지 마라
● “너”만 빼라
- “You misspelled ‘successfully’” —> “sucessfully -> successfully”
- 저자에 대한 판단에서 단순한 정정으로 변경
● “너”를 “우리”로 변경하라
- Can you rename this variable to something more descriptive, like
seconds_remaining ? —>
- Can we rename this variable to something more descriptive, like
seconds_remaining ?
- “우리”는 팀의 코드에 대한 단체 책임을 강화함
- 저자나 리뷰어는 다른 회사로 이직할 수 있지만, 코드를 소유한 팀은 어떠한 형태로
든 회사에 남는다.
● 주어만 빼라
- ~하는 것을 제안합니다. ~하는게 어떨까요.
14. 14
7. 피드백은 명령이 아니라 요청으로 표현해라
● 동료에게 명령하지 않는다
- ex. 스테이플러 좀 줘. 그리고 음료수 좀 가져다 줘
● 하지만 리뷰에서는 강압적인 명령을 종종 본다.
- ex. 이 클래스를 별도의 파일로 분리하라.
● ex.
- Foo 클래스의 별도의 파일로 분리하라 —>
- Foo 클래스를 별도의 파일로 분리할 수 있을까요 ?
15. 15
8. 의견이 아니라 원칙에 기반하여 피드백하라
● 저자에게 의견을 줄 때는
- “제안하는 변경”과 “변경의 이유”를 모두 설명하라.
- ex. 이 클래스를 2개로 분리해야 해요 —> 지금 이 클래스는 파일 다운로드와 파싱의
2가지 책임을 가지고 있어요. 다운로더와 파서 2개의 클래스로 분리하여 SRP를 준수해
야 해요.
● SW는 과학인 동시에 예술 ???
- 항상 원칙에 기반하여 정확히 뭐가 잘 못 되었는지 언급할 수 있는 것은 아니다
- 단지 그냥 보기 싫거나 직관적이지 않을 수 있다.
- 무엇을 할 수 있는지 객관적으로 설명하라
- ex. This is confusing —> I found this hard to understand
16. 16
나의 최악의 코드리뷰 사례
● S가 내게 보낸 첫번째 Changelist. 너무 대충. 파이썬 처음 해 본...
● 의무감을 가지고 모든 이슈를 기록(60군데). 너무 많은 실수를 찾
아낸 나는 훌륭한 리뷰어 ???
● 몇 일 후 S는 Updated Changelist를 보냄
- 커멘트에 대한 응답. 간단한 수정(변수명 변경, 오타 수정 등) 포함
- 하지만 고수준 문제에 대한 언급 거부(정의되지 않은 행위, 잘못된 형식을 갖는 입력,
6단계까지 중첩되는 복잡한 제어문 등)
● 화가 나서 새로운 커멘트를 보냄(전문가 다운 어투로)
● 1주가 지난 지금도 동일 리뷰에 대해서 설왕설래 중. 이젠 더 이상
S와 같은 사무실에 있기 싫다 ㅠㅠ
● 3주가 지났는데 코드가 거의 변하지 않았다.
17. 17
중재(Intervention)
● Bob(최고 시니어 개발자)이 우리가 전에 시도하지 않았던 2개의
작은 라이브러리를 분리하는 것(각각 30~50 LOC)에 대한
Changelist 작성을 S에게 요구하면 리뷰를 시작
● S가 해당 업무를 수행하면 Bob은 즉각 승인
● 그런 다음 Bob은 메인 Changelist(200 LOC를 정리하는)에 도달
- 몇개의 작은 제안을 하고,
- Changelist를 승인
● Bob의 전체 리뷰은 이틀만에 완료
18. 18
Techniques
9. 한두 등급만 코드 레벨을 올리는 것을 목표하라
10. 반복적인 패턴에 대해서 피드백을 제한하라
11. 리뷰의 범위를 존중하라
12. 큰 리뷰를 잘게 나눌 기회를 찾아라
13. 진정한 칭찬을 해라
14. 사소한 이슈만 남았다면 승인해라
15. 교착상태를 적극적으로 처리해라
19. 19
9. 한두 등급만 코드 레벨을 올리는 것을 목표하라
● D 등급의 Changelist를 받으면 저자가 C나 B 등급을 받도록 도와
라
● 완전하지는 않아도 충분히 좋은 코드가 되도록
● F
- 기능적으로 틀렸거나
- 너무 복잡해서 정합성에 확신이 없는 상태
● 승인을 보류하는 유일한 이유
- 수 차례의 리뷰 라운드 후에도 코드가 F 상태인 경우
20. 20
10. 반복적인 패턴에 대해서 피드백을 제한하라
● 저자의 실수가 동일한 패턴임을 식별 했다면 모든 경우를 언급하
지 말라.
● 동일 패턴에 대해서 2~3개 정도의 예를 언급하라. 그 이상은 저자
에게 개별 사례가 아니라 패턴에 대해서 수정을 요구하라.
21. 21
11. 리뷰의 범위를 존중하라
● 자주 보이는 Anti-Pattern
- 리뷰어가 Changelist 근처의 코드를 보고 저자에게 수정을 요청하는 것
● Rule of thumb: Changelist에 포함되지 않은 라인은 리뷰 범위
가 아님
● 예외: Changelist가 둘러싼 코드에 영향을 미칠 때
22. 22
12. 큰 리뷰를 잘게 나눌 기회를 찾아라
● 400 LOC 이상의 리뷰는 작게 분리하도록 저자에게 제안
● 저자가 Changelist를 분리하는 번거로운 일에 불평할 수 있다
- 분리를 위한 논리적 경계를 식별해서 짐을 덜어줘라
- 예.
- 여러 파일에 걸쳐 변경했다면 파일별로 리뷰를 나눠라
- 추상화 수준이 낮은 함수나 클래스를 찾아서 별도의 리뷰로 분리 제안
- 코드 품질이 낮을 때 리뷰 분리를 강조
- 나쁜 코드 리뷰는 LOC가 늘면 기하급수적으로 어려워짐
23. 23
13. 진정한 칭찬을 해라
● 대부분의 리뷰어가 코드의 잘못된 부분에만 집중
● 하지만 리뷰는 긍정적 행위 강화를 위한 값진 기회이기도 함
● Changelist에서 리뷰어를 기쁘게 할 때마다
- “오 이런 API가 있나요. 정말 유용해요”
- “정말 좋은 해결책이네요. 생각도 못 했네요”
- “이 함수를 분리한 것은 좋은 아이디어에요. 훨씬 단순해 졌어요”
● 저자가 쥬니어 혹은 최근에 합류했다면 리뷰에 매우 민감하고 방
어적일 것이다.
● 진심어린 칭찬은 리뷰어가 잔인한 감시자가 아니라 도와주려는
팀동료라는 것을 보여서 이런 긴장감을 낮춰준다.
24. 24
14. 사소한 이슈만 남았다면 승인해라
● 모든 커멘트가 수정되는 것을 확인하고 나서야 승인하려는 오해
존재
- 불필요한 코드 리뷰 라운드를 추가. 저자/리뷰어 모두 시간 낭비
● 아래 조건 중 하나라도 만족되면 승인
- 더 이상 커멘트가 없을 때
- 남겨진 커멘트가 사소한 이슈(변수명 변경, 오타 등)
- 남겨진 커멘트가 선택적 제안(Optional Suggestion)
- ex. 높은 수준의 Refactoring/Design Pattern 적용 등
25. 25
15. 교착상태를 적극적으로 처리해라
● 코드 리뷰의 최악의 결과는 교착상태(Stalemate)
- 추가적인 변경을 안하면 Changelist 승인 거부
- 저자는 변경을 거부
● 교착상태로 향하는지 나타내는 표식
- 토론의 톤이 점차 팽팽해지고 공격적으로 됨
- 라운드당 커멘트가 줄어드는 경향을 갖지 않는다
- 너무 많은 커멘트에 저항을 갖는다
26. 26
15. 교착상태를 적극적으로 처리해라
● 만나서 얘기하라
- 화상 혹은 만나서 논의
- 텍스트 기반 의사소통은 상대가 인간이라는 것을 잊게 한다
● 설계 리뷰를 고려하라
- 코드 리뷰때 설계 리뷰때 논의 되었어야 할 사항을 논쟁하는가 ?
- 설계 리뷰는 있었나 ?
● 인정하거나 Escalate하라
- 교착상태가 길어지면 관계가 나빠진다
- 그냥 승인하는 비용
- 저수준의 코드를 무심코 승인하면 품질이 좋은 SW를 만들 수 없다.
- 또한 동료와 너무 다퉈서 함께 일하지 않는다면 고수준의 품질을 얻을 수 없다
- 아주 심각하지 않다면 그냥 인정하고 좋은 관계로 동료와의 협업을 지속해라
27. 27
15. 교착상태를 적극적으로 처리해라
● 인정이 불가한 경우
- 저자에게 논의를 팀장이나 테크 리더에게 Escalation 권유
- 다른 리뷰어에게 할당을 권유
● 교착상태로 부터 회복
- 상황을 관리자와 논의하라
- 휴식을 가져라. 가능하다면 안정될 때까지 CR을 서로 보내지 마라
- 갈등 해결책을 학습하라
28. 28
My worst code review: revisited
● 잘못한 점
- S의 첫번째 리뷰
- 평가 받는다고 느끼거나 방어적일 수 있다.
- 고수준 커멘트만으로 시작했으면 좋았다.
- 많은 수의 커멘트로 공격 당하는 느낌을 받지 않도록
- 리뷰어의 역할은 방해가 아니라 개선을 돕는 것임을 보였어야
- 코드 예제 제시, 변경 분에 대한 긍정적 언급 등
- 교착상태가 길어지도록 방치
- 만나서 깊은 갈등에 대해서 언급 or 관리자에게 Escalate했어야
● Bob이 잘한 점
- 처음에 리뷰를 분리한 것. 2개의 코드 블럭을 머지하면서 관계가 좋아짐
- 여전히 문제가 있었지만 문제는 작어졌고, Changelist를 관리하기 쉬워졌음
- 리뷰를 완전하도록 억압하지 않았다
29. 29
Reference
● How to Do Code Reviews Like a Human (Part One)
● https://mtlynch.io/human-code-reviews-1
● How to Do Code Reviews Like a Human (Part Two)
● https://mtlynch.io/human-code-reviews-2/