코드 검토를 위해 제출 된 코드가 너무 복잡해 보이는 경우 어떻게해야합니까?


115

코드는 따르기가 어렵지만 적어도 피상적 인 테스트에서는 (대부분) 잘 작동하는 것으로 보입니다. 여기 저기에 작은 버그가있을 수 있지만 더 깊은 문제 또는 간단한 수정의 증상이 있는지 코드를 읽고 말하기가 매우 어렵습니다. 그러나 코드 검토를 통해 전체 정확성을 수동으로 확인하는 것은 가능하다면 매우 어렵고 시간이 많이 걸립니다.

이 상황에서 가장 좋은 행동 방법은 무엇입니까? 끝까지 고집? 부분적인 도버? 먼저 리팩토링? 버그만 수정하고 기술 부채를 수락 하시겠습니까? 해당 옵션에 대한 위험 평가를 수행 한 후 결정합니까? 다른 것?


4
나타 납니까? 소스 파일을 빠르게 측정하면 의심이 확인되거나 거부됩니다. 측정 후 코드 검토시 측정 수치를 불러 와서 복잡한 수치를 낮추기위한 리팩토링을 제안하십시오.
Jon Raynor



4
"너무 복잡한"을 정의하십시오. 코드가 팀에 익숙하지 않은 잘 알려진 디자인 패턴 을 사용 하거나 팀에 잘 알려진 패턴 을 사용 하지 못해 코드가 너무 복잡 합니까? 코드가 너무 복잡하다고 판단하는 정확한 이유는 앞으로 나아가는 방법에 대한 올바른 평가를 작성하는 데 필수적입니다. 코드 검토만큼 깊고 복잡한 지식 영역에서 "너무 복잡하다"는 단순한 설명은 개발자가 저에게 마녀 사냥을 제안합니다.
Pieter Geerkens

7
@PieterGeerkens 아니면 복잡한 문제를 해결하기 때문에 너무 복잡합니까?
Casey

답변:


251

검토 할 수 없으면 검토를 통과 할 수 없습니다.

코드 검토는 버그를 찾기위한 것이 아니라는 것을 이해해야합니다. 이것이 QA의 목적입니다. 코드 검토는 향후 코드 유지 관리가 가능하도록하기위한 것입니다. 지금 코드를 따라갈 수 없다면 6 개월 안에 기능 향상 및 / 또는 버그 수정을 수행 할 수있는 방법은 무엇입니까? 지금 버그를 찾는 것은 부수적 인 이점입니다.

너무 복잡하면 많은 SOLID 원칙을 위반하는 입니다. 리팩터링, 리팩터링, 리팩터링 그것을 훨씬 덜 간단하게하는 적절한 이름의 함수로 나눕니다. 정리하면 테스트 케이스가 계속 제대로 작동하는지 확인할 수 있습니다. 테스트 사례가 있습니까? 그렇지 않은 경우 추가를 시작해야합니다.


49
아주 많이 요 이 코드를 읽는 사람과 작가 만이 아닙니다. 또한 10 년 안에 임의의 인턴이 될 것이므로, 무슨 일이 일어나고 있는지 이해할 수있는 기회를 갖기를 원합니다.
David Grinberg

2
좋은 대답입니다. "코드 검토"의 목적에 따라 다릅니다. 가독성은 하나의 구조이고 다른 구조는 매우 밀접한 관련이 있습니다. fwiw MAJOR Corps가 작성한 오픈 소스로 작업하고 있으며 var 및 fn 이름이 너무 머리가 커서 거의 읽을 수 없습니다.

19
@DavidGrinberg 모든 실용적인 목적으로 "6 개월 만에"는 완전히 다른 사람입니다.
chrylis

2
코드를 잠시 동안 치워 두십시오 (모든 것을 기억하지 못할 정도로 길다). 원본 코더에게 검토를 요청하십시오. 그가 이해하는지보십시오.
Nelson

4
버그 검토에 대한 코드 검토가 " 아니오 " 라는 의견에 동의하지 않습니다 . 버그를 발견하는 경우가 많으며 코드 검토에서 매우 강력하고 유용한 부분입니다. 더 나은 방법은 향후 코드에서 버그를 완전히 피할 수있는 방법을 찾는 데 도움이됩니다. 요점은 아마도 과장되어 있으며 버그를 독점적 으로 찾는 것이 아니라는 것입니다 !
Cody Grey

45

언급 한 모든 것은 코드 검토에서 지적하기에 완벽하게 유효합니다.

코드 검토를 받으면 테스트를 검토합니다. 테스트가 충분한 범위를 제공하지 않으면 지적해야 할 부분입니다. 테스트는 코드가 의도 한대로 작동하고 변경에서 의도 한대로 계속 작동하는지 확인하는 데 유용해야합니다. 실제로 이것은 코드 검토에서 가장 먼저 찾는 것 중 하나입니다. 코드가 요구 사항을 충족한다는 것을 입증하지 못했다면 코드를 보는 데 시간을 투자하고 싶지 않습니다.

코드에 대한 충분한 테스트가 완료되면 코드가 복잡하거나 따르기 어려운 경우 사람도 살펴 봐야합니다. 정적 분석 도구는 코드에서 잠재적 인 결함을 찾을뿐만 아니라 복잡성에 대한 몇 가지 측정 방법을 제시하고 지나치게 복잡한 방법을 표시 할 수 있습니다 (인간 코드 검토 전에 실행해야 함). 그러나 코드는 사람이 읽고 유지 관리하며 유지 관리 성을 위해 먼저 작성해야합니다. 유지 보수가 덜 쉬운 코드를 사용해야하는 이유가있는 경우에만 해당 방식으로 작성해야합니다. 복잡하거나 직관적이지 않은 코드가 필요한 경우, 코드가 왜 그런지 문서화해야하며 (코드에) 코드가 왜 그런지 미래의 개발자가 코드가 왜, 무엇을하고 있는지 이해할 수있는 유용한 주석이 있어야합니다.

적절한 테스트가 없거나 충분한 이유없이 코드가 지나치게 복잡한 코드 검토를 거부하는 것이 이상적입니다. 앞으로 나아가 야 할 사업상의 이유가있을 수 있으므로 위험을 평가해야합니다. 기술 부채가 코드로 진행되는 경우, 변경해야 할 사항과 변경 제안 사항과 함께 티켓을 버그 추적 시스템에 즉시 넣습니다.


30

그러나 코드 검토를 통해 전체 정확성을 수동으로 확인하는 것은 가능하다면 매우 어렵고 시간이 많이 걸립니다.

그것은 원격으로 코드 검토의 요점이 아닙니다. 코드 검토를 생각하는 방법은 코드에 버그가 있다고 생각하여 수정해야합니다. 이 사고 방식으로 코드 (특히 주석)를 탐색하고 "문제를 좁힐 수 있도록 진행중인 작업의 큰 그림을 이해하는 것이 쉬운가?" 그렇다면 패스입니다. 그렇지 않으면 실패입니다. 최소한 더 많은 문서가 필요하거나 코드를 합리적으로 이해할 수 있도록 리팩토링이 필요할 수 있습니다.

그것이 고용주가 추구하는 것이 확실하지 않다면 그것에 대해 완벽 주의자가되지 않는 것이 중요합니다. 대부분의 코드는 너무 빨라서 한 번에 10 번씩 쉽게 리팩터링 할 수있어 매번 더 읽을 수 있습니다. 그러나 고용주는 세계에서 가장 읽기 쉬운 코드를 사용하기 위해 지불하기를 원하지 않을 것입니다.


4
좋은 의견! 이런, 내가 그 :) 일을 유죄 "대부분의 코드는 쉽게 때마다 더 읽기지고, 연속 10 회 리팩토링 될 수 있음을 너무 많이 짜증"
딘 래드클리프을

1
"대부분의 코드는 너무 빨라서 한 번에 10 번씩 쉽게 리팩터링 할 수있어 매번 더 읽기가 쉽습니다." 실제로 그것이 현실에있는 방법입니다.
Peter Mortensen

@PeterMortensen 실세계에서 많은 것을 발견한다는 것은 사실입니다. 그러나 코드를 그런 식으로 작성하는 것은 누구에게도 도움이되지 않습니다. 나는 그것이 두 가지 이유가 있다고 생각합니다. 개발자가받는 교육은 읽을 수있는 코드 작성 방법을 가르치는 데 거의 노력을 기울이지 않았습니다. 그리고 일부 기업에서는 "개발자가 이미 작업 코드를 작성했다면 읽을 수 있는지 여부를 신경 써야하는 이유는 무엇입니까?"라고 시간 낭비로 인식합니다.
kasperd

15

그러나 코드 검토를 통해 전체 정확성을 수동으로 확인하는 것은 가능하다면 매우 어렵고 시간이 많이 걸립니다.

몇 년 전, 실제로 학생들의 숙제를 채점하여 정확히 그렇게하는 것이 저의 일이었습니다. 그리고 많은 사람들이 여기저기서 버그로 합리적인 품질을 제공했지만 눈에 띄는 두 사람이있었습니다. 둘 다 항상 버그가없는 코드를 제출했습니다. 하나의 제출 코드는 고속에서 위아래에서 읽을 수 있으며 아무런 노력없이 100 % 정확하다고 표시합니다. 다른 하나는 다른 하나의 WTF 인 코드를 제출했지만 어떤 방식 으로든 버그를 피할 수있었습니다. 표시하는 절대적인 고통.

오늘날 두 번째 코드는 코드 검토에서 코드가 거부됩니다. 정확성을 확인하는 것이 매우 어렵고 시간이 많이 걸리는 경우 코드에 문제가 있습니다. 괜찮은 프로그래머는 문제를 해결하는 방법을 알아 내고 (X 시간이 걸립니다) 코드 검토에 리팩터링하기 전에 작업을 수행하는 것이 아니라 분명히 작업을 수행합니다. X보다 시간이 훨씬 적게 걸리고 앞으로 많은 시간이 절약됩니다. 버그는 코드 검토 단계로 넘어 가기 전에 버그를 찾아내는 경우가 많습니다. 다음으로 코드를 훨씬 빠르게 검토합니다. 그리고 코드를보다 쉽게 ​​적용 할 수있게함으로써 미래에도 항상

또 다른 답변에 따르면 일부 사람들의 코드는 10 번 리팩토링 될 수 있으며 매번 더 읽기 쉬워집니다. 슬프다. 다른 직업을 찾아야하는 개발자입니다.


코드를 10 번 리팩토링하는 데 훨씬 적은 시간이 소요되며, 코드의 첫 번째 버전을 작성하는 데 소요됩니다. 다른 사람이 내가이 리팩토링을 수행했다는 것을 알고 있다면 실패했습니다.
Ian

6

오래된 코드 가 약간 변경 되었습니까? (10000 줄 코드베이스에서 100 줄의 코드가 변경됨) 여전히 약간의 변화가 있습니다. 때로는 시간 제약이 있으며 개발자는 단순히 완전한 재 작성이 더 오래 걸리고 예산을 벗어 났기 때문에 오래되고 불편한 프레임 워크에 머물러 있어야합니다. . + 보통 위험이 수반되며, 잘못 평가하면 수백만 달러가 소요될 수 있습니다. 오래된 코드라면 대부분의 경우 코드와 함께 살아야합니다. 스스로 이해하지 못하는 경우, 그들과 이야기하고 그들이하는 말을 듣고 이해하려고 노력하십시오. 따라 가기가 어려울 수 있지만 다른 사람들에게는 완벽하게 좋습니다. 그들의 편을 잡고 그들의 끝에서 그것을보십시오.

새 코드 입니까? 시간 제약에 따라 가능한 한 리팩토링하도록 옹호해야합니다. 필요한 경우 코드 검토에 더 많은 시간을 보내는 것이 좋습니다. 당신은 15 분 자신을 타임 박스하지 말고 아이디어를 얻고 계속하십시오. 저자가 일주일 동안 무언가를 쓰는 데 4 ~ 8 시간을 소비해도 괜찮습니다. 여기서 목표는 리팩토링을 돕는 것입니다. "refactor. now"라는 코드 만 반환하지는 않습니다. 어떤 방법으로 분류 할 수 있는지 확인하고 새로운 수업 등을 소개하는 아이디어를 생각해보십시오.


2
"refactor. now"라는 코드를 반환하지 않는 이유는 무엇입니까? 나는 그러한 검토 의견을 적어도 한 번 받았으며 지난 번에는 도움이되고 정확하다는 것을 기억합니다. 나는 처음부터 큰 코드 덩어리를 다시 작성해야했고, 이것이 옳은 일이었다. 과거를 되돌아 보면 오래된 코드가 구할 수없는 혼란이라는 것을 스스로 알았 기 때문이다. 검토는 것을 알 자격이 단순히 충분했다 (나는 분명히하지 않았다)
모기

4
@ gnat : 무례하기 때문에 하나. 코드의 문제점을 설명하고 다른 사람이 코드를 개선 할 수 있도록 노력하면 더 좋아 보입니다. 그렇지 않으면 대기업에서는 문에서 빨리 벗어날 수 있습니다. 특히 상급자의 코드를 검토하는 경우.
Neolisk

제가 위에서 언급 된 경우, 그것은 단지에 대해 충분히주의하는 일이 큰 회사 설립에 있었다 하지 에 물었을 때, 적어도 직접 전문 기술을 공유하는 이유로, 가장 자격을 갖춘 개발자 문 밖으로 점점
모기

1
@gnat : "refactor. now"접근 방식은 아래쪽으로 작동 할 수 있습니다. 즉, 10 년 이상의 경험이있는 선임 개발자가 경험이 없거나 유사한 상황없이 1 개월 전에 고용 된 주니어 개발자를 리팩토링한다고 말하면. 위로-문제가있을 수 있습니다. 다른 개발자의 경험이 어느 정도인지 모르기 때문에 기본 동작으로 간주하는 것이 안전합니다. 그것은 당신을 확실히 아프게하지 않을 것입니다.
Neolisk

1
@Neolisk : 시간의 압력 코드를 작성했고, 경험이 풍부한 개발자 알고 당신이 그에게 시간과 향상을위한 변명을주는 코드를 거부 할 경우 충분히 너무나 행복 할 수 좋지 않다. PHB가 충분히 좋다고 결정하면 개발자가 불행 해집니다. 평가자가 좋지 않다고 판단하면 그를 행복하게 만듭니다.
gnasher729

2

종종 "복잡한"패치 / 변경 목록은 한 번에 많은 다른 작업을 수행하는 것입니다. 새로운 코드, 삭제 된 코드, 리팩토링 된 코드, 이동 된 코드, 확장 된 테스트가 있습니다. 큰 그림을보기가 어렵습니다.

일반적인 단서 힌트는 패치가 크지 만 설명이 작다는 것입니다 : "Implement $ FOO".

그러한 패치를 처리하는 합리적인 방법은 패치를 일련의 더 작은 독립된 조각으로 나누는 것입니다. 단일 책임 원칙에 따르면 함수가 한 가지만 수행해야한다고하는 것처럼 패치도 한 가지에만 중점을 두어야합니다.

예를 들어, 첫 번째 패치에는 기능적 변경을하지 않는 완전히 기계적인 리팩토링이 포함될 수 있으며, 마지막 패치는 산만 함과 청어가 적고 $ FOO의 실제 구현 및 테스트에 중점을 둘 수 있습니다.

많은 새로운 코드가 필요한 기능의 경우, 시리즈의 마지막 패치가 실제로 새로운 코드 (플래그 플립)를 호출 할 때까지 제품의 동작을 변경하지 않는 테스트 가능한 청크로 새 코드를 도입 할 수 있습니다.

이것을 재치있게 수행하는 것에 관해서는, 나는 보통 그것을 내 문제라고 말한 다음 저자의 도움을 요청한다. 함께?" 더 작은 단계에 대해 구체적인 제안을해야하는 경우가 있습니다.

"Implement $ FOO"와 같은 큰 패치는 다음과 같은 일련의 패치로 바뀝니다.

  1. $ FOO를 구현하기 위해 vector 이외의 시퀀스로 호출해야하므로 한 쌍의 반복자를 사용하는 새 버전의 Frobnicate를 소개합니다.
  2. Frobnicate의 기존 발신자를 모두 전환하여 새 버전을 사용하십시오.
  3. 이전 Frobnicate를 삭제하십시오.
  4. Frobnicate는 너무 많은 일을하고있었습니다. 리플 럼핑 단계를 자체 방법으로 인수 화하고 테스트를 추가하십시오.
  5. 테스트와 함께 Zerzify를 소개하십시오. 아직 사용하지는 않았지만 $ FOO에 필요합니다.
  6. Zerzify 및 새로운 Frobnicate 측면에서 $ FOO를 구현하십시오.

1-5 단계는 제품의 기능을 변경하지 않습니다. 그들은 당신이 모든 올바른 시험을 가지고 있는지 확인하는 것을 포함하여 사소한 검토입니다. 6 단계가 여전히 "복잡한"경우에도 최소한 $ FOO에 중점을 둡니다. 그리고 로그는 당연히 $ FOO가 어떻게 구현되었는지 (그리고 Frobnicate가 변경된 이유)에 대한 더 나은 아이디어를 제공합니다.


Git을 사용하는 경우 한 가지 방법은 여러 커밋의 풀 요청을 작성하는 것입니다. 각 커밋은 가능한 한 원자적이고 독립적이며 자체 설명이 있습니다. 그런 다음 PR 본문에 각 변경 사항을 수동으로 검토 할 수있는 유용한 메모를 추가하십시오. 이것이 일반적으로 글로벌 리팩터링과 같은 초대형 PR이나 공격 할 수없는 크고 큰 툴링 변경을 처리하는 방법입니다.
Jimmy Breck-McKye

1

다른 사람들이 지적했듯이 코드 검토는 실제로 버그를 찾도록 설계되지 않았습니다. 코드 검토 중 버그를 발견하면 자동화 된 테스트 범위가 충분하지 않을 수 있습니다 (예 : 단위 / 통합 테스트). 코드가 예상대로 작동한다고 확신 할 수있는 범위가 충분하지 않은 경우 , 나는 보통 더 많은 테스트를 요청하고 내가 찾고있는 테스트 사례의 종류를 지적하고 일반적으로 적절한 범위를 갖지 않는 코드베이스에 코드를 허용하지 않습니다. .

높은 수준의 아키텍처가 너무 복잡하거나 이해가되지 않는 경우 일반적으로 몇 명의 팀원과 회의를 통해 이야기를합니다. 나쁜 아키텍처에서는 반복하기가 어려운 경우가 있습니다. 개발자가 초보자라면, 나는 보통 잘못된 풀 요청에 반응하는 대신 그들의 생각이 미리 진행 되는 것을 검토해야합니다. 문제가 분명하게 해결 될 수있는 명확한 해결책이없는 경우에는 더 노련한 개발자에게도 마찬가지입니다.

복잡성이 분석법 수준으로 격리 된 경우 일반적으로 반복적이고 올바른 자동 테스트로 수정할 수 있습니다.

마지막 요점 검토 자로서 코드의 복잡성이 필수적 이거나 우발적 복잡성 인지 여부를 결정해야합니다 . 본질적인 복잡성은 합법적으로 해결하기 어려운 소프트웨어 부분과 관련이 있습니다. 우연한 복잡성은 우리가 작성하는 코드의 다른 모든 부분을 아무 이유없이 너무 복잡하고 쉽게 단순화 할 수있는 것을 말합니다.

필자는 일반적으로 필수 복잡성을 가진 코드가 진정으로 단순하고 더 이상 단순화 될 수 없는지 확인합니다. 또한이 부분에 대한 더 많은 테스트 범위와 좋은 문서화를 목표로합니다. 풀 요청 프로세스 동안 우발적 인 복잡성을 제거해야합니다. 왜냐하면 코드는 우리가 처리하는 대부분의 코드이므로 단기적으로도 유지 보수의 악몽을 유발할 수 있기 때문입니다.


0

테스트는 어떻습니까? 그들은 단 하나의 주장으로 명확하고 단순하며 읽기 쉽다. 테스트는 의도 된 동작과 코드의 사용 사례 를 명확하게 문서화해야 합니다.

제대로 테스트되지 않은 경우 검토를 시작하기에 좋은 곳입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.