왜 당신의 코드는 작동하지만 코드 리뷰에서 여전히 거절당할까
Source: Dev.to
번역할 텍스트를 제공해 주시면, 요청하신 대로 한국어로 번역해 드리겠습니다.
(코드 블록, URL 및 마크다운 형식은 그대로 유지됩니다.)
혹시 모든 테스트가 통과하고 기능이 완벽히 동작하는데도 “Request Changes” 라는 빨간색 알림을 받은 적 있나요?
네, 저도 경험해봤습니다. “하지만 동작하잖아요!” 라고 생각하면서 답답함을 느끼죠.
동작하는 코드는 최소 기준일 뿐, 최종 목표가 아닙니다.
코드 리뷰에 숨겨진 규칙에 대해 이야기해 보겠습니다.
1. 인지 부하
코드는 한 번만 읽히는 것이 아닙니다. 수백 번 읽히게 됩니다. 누군가 버그를 디버깅하거나, 기능을 추가하거나, 시스템 동작을 이해하려 할 때마다 여러분의 코드를 읽게 됩니다.
나쁜 예시
d = datetime.now()
y = d.year
m = d.month
dy = d.day
동작하고 테스트도 통과하지만, 읽는 사람은 각 변수의 의미를 머리로 해석해야 합니다. 이것이 인지 부하입니다.
좋은 예시
today = datetime.now()
year = today.year
month = today.month
day = today.day
스스로 문서화된 형태입니다. 독자는 의도를 즉시 파악하고 실제 로직으로 넘어갈 수 있습니다.
좋은 코드는 당신이 작성한 것 때문에 똑똑해지는 것이 아니라, 다음 사람이 코드를 읽으며 똑똑함을 느끼게 합니다.
2. 조기 추상화
아, 이건 제가 가장 많이 저지른 실수 중 하나입니다. 디자인 패턴에 신이 나서 DataProcessorFactory와 ProcessorRegistry, 그리고 전략 패턴까지 만들었는데, 실제로는 하루에 한 번 실행되는 기능이었습니다.
YAGNI 라는 원칙이 있습니다 – You Aren’t Gonna Need It (필요 없을 거예요).
추상화는 강력하지만 비용이 따릅니다:
- 각 추상화 레이어는 버그가 숨어 있을 수 있는 또 다른 장소가 됩니다.
- 각 인터페이스는 미래의 개발자가 이해해야 할 또 다른 대상이 됩니다.
경험 법칙: 패턴의 구체적인 예시가 최소 세 개 이상 있을 때만 추상화하세요. 두 개는 우연일 뿐, 세 개가 패턴입니다.
3. “왜”를 놓치기
주석은 무엇을 설명하는 것이 아니라 왜를 설명해야 합니다. 코드는 이미 무엇을 하고 있는지를 보여줍니다.
// convert to milliseconds
return seconds * 1000;
이 주석은 가치가 없습니다—코드 자체가 변환임을 명시하고 있습니다.
// API가 5초 후에 타임아웃되므로, 버퍼를 두고 4.5 s를 사용합니다
return seconds * 4500;
이제 비즈니스 로직을 문서화하고, 특정 숫자가 왜 중요한지 설명하고 있습니다.
재시도 로직도 마찬가지
// BAD: "Retry 3 times"는 코드만 보고도 명확합니다.
// GOOD: 서드파티 API가 가끔 503 오류를 반환합니다;
// 재시도는 보통 3번 이내에 성공합니다.
for (let i
주니어는 무엇이 일어나야 하는지를 생각합니다.
시니어는 무엇이 일어날 수 있는지를 생각합니다.
7. 매직 넘버
50은 무슨 의미일까요? 300000은? 0.0은?
(원본 내용이 여기서 끊겼습니다—매직 넘버 대신 이름이 지정된 상수나 설정 값을 사용하고, 그 목적을 설명하는 주석을 추가하세요.)
더 많은 실전 팁을 원하신다면?
제 25년의 프로덕션 현장 경험을 유튜브 채널에서 확인하세요: 🛠️👉
0.75는 무엇을 의미하나요?
if (users.length > 50) paginate();
setTimeout(retry, 300000);
if (score > 0.75) approve();
이 숫자들은 지금은 당신에게는 의미가 있을지 모르지만, 다른 사람에게는 의미가 없으며 — 3개월 후에도 당신에게는 의미가 없을 것입니다.
명명된 상수 사용
const MAX_USERS_PER_PAGE = 50;
const RETRY_DELAY_MS = 300_000; // 5 minutes
const SUCCESS_THRESHOLD = 0.75;
MAX_USERS_PER_PAGE는 이야기를 전달합니다. 제품 관리자가 임계값을 변경해 달라고 요청하면, 이를 빠르게 찾아 자신 있게 변경하고 싶을 것입니다. 명명된 상수는 이를 가능하게 합니다.
8. 테스트 단축키
테스트는 통과하지만, 실제로 테스트하고 있는 걸까요?
expect(result).toBeTruthy();
이 테스트는 함수가 1, true, "hello" 혹은 문자 그대로 어떤 비‑Falsy 값이라도 반환하면 통과합니다. 코드가 실제로 올바르게 동작하는지에 대해서는 전혀 알려주지 못합니다.
좋은 테스트는 특정 동작을 검증합니다
expect(result.email).toBe("user@example.com");
expect(result.name).toBe("Jane Doe");
expect(result.id).toBeDefined();
테스트는 코드가 해야 할 일을 문서화합니다. 리팩터링을 할 때 아무것도 깨지지 않았다는 확신을 줍니다. 테스트는 미래의 개발자를 위한 문서이므로, 의미 있게 작성하세요.
코드 리뷰의 진정한 목표
코드 리뷰는 실제로 버그를 찾는 것이 아닙니다. 현대적인 테스트가 대부분을 잡아줍니다.
코드 리뷰는 지식 공유에 관한 것입니다. 시간이 지나도 코드 품질을 유지하는 것, 엣지 케이스를 잡아내고 장기적인 유지 보수를 보장하는 것이 목적입니다.
리뷰어가 무언가를 변경하라고 할 때, 그들이 여러분의 코드가 작동하지 않는다고 말하는 것이 아니라, 다음과 같은 의미입니다:
- “이렇게 하면 유지 보수가 더 쉬워집니다”
- “우리의 패턴에 더 잘 맞습니다”
- “미래의 당신이 이 명확성에 감사할 것입니다.”
다음 PR을 제출하기 전에 스스로에게 물어보세요:
- 6개월 후, 상황이 흐려졌을 때 누군가가 이 코드를 이해할 수 있을까?
- 팀의 컨벤션과 패턴을 따르고 있는가?
- 가능한 한 단순하지만, 더 단순하지는 않은가?
- 오류를 우아하게 처리하고 있는가?
동작하는 코드는 최소 기준일 뿐, 최종 목표가 아닙니다. 훌륭한 코드는 사라지는 코드 — 미래의 개발자들이 눈에 띄지 않을 정도로 명확하고 구조화된 코드입니다. 그들은 단지 이해하고 넘어갑니다.
You’re not writing code for computers. Computers don’t care if your variables are named
xoruserAccountBalance. You’re writing code for humans.
2 AM에 생산 버그를 고치려는 피곤한 개발자를 위해 코드를 작성하세요. 시스템이 어떻게 동작하는지 이해하려는 새로운 팀원을 위해 코드를 작성하세요. 모든 것을 잊어버린 채 6개월 후의 자신을 위해 코드를 작성하세요.
가장 답답한 코드 리뷰 피드백은 무엇인가요? 아래 댓글에 남겨주세요.
Note: This article was written with AI assistance to help structure and articulate 25+ years of debugging experience. All examples, insights, and methodologies are from real‑world experience.