코드 품질

Code Quality

개념

만든 코드를 반년 뒤의 다른 사람이 읽고 고칠 수 있는 상태로 두는 일이며, 나중에 드는 수정 비용을 줄이는 데 씁니다.

등장 배경

코드가 돌아가면 끝이라고 보던 시절이 있었습니다. 화면이 뜨고 버튼이 눌리면 그 코드는 제 몫을 한 것이고, 안이 어떤 모양인지는 만든 사람 말고 아무도 들여다보지 않았습니다. 서비스가 한두 해 안에 끝나거나 만든 사람이 계속 그 자리에 앉아 있으면 이 방식이 실제로 통했습니다. 머릿속에 지도가 들어 있는 사람이 옆에 있으면 코드가 어떻게 생겼든 고치는 데 오래 걸리지 않기 때문입니다.

사람이 바뀌고 해가 넘어가면서 이 전제가 깨졌습니다. 페이지덱에서 태오가 결제 실패 안내 문구 한 줄을 바꿔 달라는 요청을 받은 날이 그랬습니다. 한 시간이면 된다고 답했는데 사흘이 걸렸습니다. 같은 문구가 네 곳에 흩어져 있었고, 처음 쓴 사람은 이미 회사에 없었고, 네 곳 중 어디가 실제로 고객 화면에 나가는지 코드만 봐서는 알 수 없었습니다. 세 곳을 고쳐 내보낸 다음 날 기업 고객 화면에서만 옛 문구가 그대로 떴습니다.

이런 일이 몇 번 반복되면 회의가 같은 모양으로 흘러갑니다. 한쪽은 문구 하나 바꾸는 데 왜 사흘이 걸리느냐고 묻고, 다른 쪽은 이 코드가 원래 그렇다고 답합니다. 둘 다 틀린 말이 아니어서 결론이 나지 않습니다. 겉으로 보이는 것은 늦어진 일정뿐이고, 늦어진 진짜 이유는 코드 안쪽에 있는데 그것을 가리킬 이름이 없었습니다.

코드 품질은 그 자리에 붙인 이름입니다. 기능이 되는지 안 되는지는 테스트가 답합니다. 코드가 의도대로 도는지를 사람 대신 기계가 확인하게 만들어 두는 활동입니다. 코드 품질은 그다음 질문을 맡습니다. 지금 잘 도는 이 코드를 반년 뒤의 남이 얼마나 싸게 고칠 수 있느냐입니다. 앞엣것은 지금 깨진 것을 잡고, 뒤엣것은 나중에 깨질 확률과 고치는 값을 함께 낮춥니다. 그래서 코드 품질은 다 만든 뒤에 점검하는 항목이 아니라, 매일 코드를 쓰는 방식 자체로 다뤄집니다.

분야 구성

코드 품질 아래 묶인 용어들은 네 갈래로 나뉩니다. 무엇이 나쁜 상태인지 부르는 이름이 개념이고, 그 상태를 되돌리는 것이 활동이고, 나빠진 곳을 사람보다 먼저 찾아 주는 것이 도구이고, 애초에 덜 나빠지게 하는 판단 기준이 원칙입니다.

개념은 눈에 안 보이는 상태에 이름을 주는 갈래입니다. 두 가지가 있습니다.

  1. 코드 스멜 — 당장 버그는 아닌데 구조가 나빠졌다는 신호입니다. 함수 하나가 400줄까지 늘어났거나, 같은 계산이 네 파일에 복사되어 있거나, 이름이 하는 일과 다른 경우입니다. 고장이 아니라 냄새라고 부르는 이유는 지금 멈추라는 뜻이 아니라 여기를 한 번 열어 보라는 뜻이기 때문입니다.
  2. 기술 부채 — 빨리 가려고 미뤄 둔 정리가 쌓여 나중에 더 내게 되는 비용입니다. 부채라고 부르는 것은 갚기 전까지 이자가 붙기 때문입니다. 원금은 미뤄 둔 정리 작업 자체이고, 이자는 그 상태로 다음 기능을 얹을 때마다 더 드는 시간입니다. 이번 주 하루를 아끼려고 대충 끼워 넣은 분기 처리가, 반년 뒤에는 그 근처를 건드릴 때마다 반나절씩을 가져갑니다.

활동은 쌓인 것을 되돌리는 갈래입니다. 리팩터링은 동작은 그대로 두고 구조만 바꾸는 작업입니다. 조건이 하나 붙습니다. 작업 전후로 사용자 화면에서 달라지는 것이 하나도 없어야 합니다. 앞의 문구 네 곳을 한 곳으로 합치는 일이 여기에 해당합니다. 고객이 보는 화면은 그대로인데 다음에 문구를 바꿀 사람은 한 곳만 고치면 됩니다. 동작이 그대로인지를 사람 눈으로 확인할 수 없어서, 리팩터링은 테스트가 먼저 깔려 있을 때만 안전합니다.

도구는 사람이 눈으로 보기 전에 기계가 먼저 훑는 갈래입니다. 셋이 있고 뒤로 갈수록 보는 범위가 넓습니다.

  1. 포매터 — 줄바꿈, 들여쓰기, 따옴표 같은 코드의 겉모양을 정해진 규칙대로 자동으로 맞춰 줍니다. 저장할 때마다 돌게 해 두면 모양에 관한 논쟁이 통째로 사라집니다. 들여쓰기를 두 칸으로 할지 네 칸으로 할지를 두고 리뷰에서 댓글이 오가던 시간이 0이 됩니다.
  2. 린터 — 모양이 아니라 위험한 습관을 잡습니다. 선언해 놓고 쓰지 않는 변수, 값을 비교해야 할 자리에 대입을 써 버린 실수, 빠뜨린 예외 처리 같은 것입니다. 사람이 리뷰에서 발견하면 하루가 걸리는 지적을 저장하는 순간에 빨간 줄로 알려 줍니다.
  3. 정적 분석 — 코드를 실행하지 않고 전체를 훑어 더 넓은 문제를 찾습니다. 한 파일 안이 아니라 함수와 파일 사이를 타고 다니면서, 값이 비어 있을 수 있는 경로나 외부 입력이 검사 없이 흘러 들어가는 길을 짚어 냅니다.

원칙은 코드를 쓰는 순간의 판단 기준입니다. 규칙이라기보다 갈림길에서 꺼내 보는 문장에 가깝습니다.

  1. DRY 원칙 — 같은 지식을 두 곳에 두지 말자는 원칙입니다. 앞에서 문구 하나가 네 곳에 있던 일이 이것을 어긴 결과입니다. 복사가 편한 순간은 쓰는 순간뿐이고, 값은 고치는 사람이 치릅니다.
  2. YAGNI — 필요해지기 전에는 만들지 말자는 원칙입니다. 나중에 여러 통화를 지원할까 봐 미리 만들어 둔 환율 구조가 2년째 원화만 처리하고 있다면, 그 구조는 도움이 아니라 매번 읽고 지나가야 하는 짐입니다.
  3. 보이스카우트 규칙 — 손댄 자리는 오기 전보다 조금이라도 낫게 두고 나오자는 규칙입니다. 정리를 위한 일정을 따로 받지 않고도 상태가 서서히 좋아지게 만드는 방법이라, 시간을 못 받는 팀이 먼저 꺼내는 수단입니다.

네 갈래는 나란히 놓인 목록이 아니라 한 고리로 이어집니다. 원칙을 어긴 자리에서 스멜이 나고, 스멜을 그대로 두면 부채가 쌓이고, 쌓인 부채를 갚는 작업이 리팩터링이고, 도구는 그 세 가지를 사람 눈보다 먼저 잡아 갚아야 할 양 자체를 줄입니다.

네 갈래를 다 알아도 지금 상태가 좋은지 나쁜지는 따로 재야 합니다. 코드 품질에는 체중계 눈금 같은 단일한 값이 없어서, 팀은 대신 볼 수 있는 값을 두세 개 정해 둡니다. 비슷한 크기의 수정에 평균 며칠이 걸렸는지, 한 곳을 고치려고 파일 몇 개를 같이 건드려야 했는지, 도구가 남긴 경고가 지난달보다 늘었는지 줄었는지 같은 값입니다. 어느 하나도 품질을 대표하지는 않습니다. 다만 세 값이 동시에 나빠지는 방향으로 움직이는 영역은 손볼 때가 됐다고 봅니다.

실무 용례

"이번 스프린트에 코드 품질 작업으로 이틀만 빼 주세요. 결제 쪽이 지금 상태로는 다음 기능을 못 얹습니다."

새 기능 대신 정리 시간을 달라는 요청입니다. 취향이 아니라 다음 일정을 지키기 위한 비용으로 설명하고 있습니다.

"리뷰에서 코드 품질 얘기는 기계가 못 잡는 것만 합시다."

모양과 규칙 위반은 도구에 맡기고 사람은 설계와 이름 짓기처럼 판단이 필요한 것만 보자는 제안입니다.

"지금 코드 품질이면 신규 입사자가 첫 배포까지 3주는 걸립니다."

읽기 어려운 정도를 온보딩 기간이라는 숫자로 바꿔 말한 것입니다.

페이지덱에서 이 말이 가장 자주 오가는 자리는 분기 계획 회의입니다. 규원이 다음 분기에 내보낼 기능 목록을 묻고, 태오가 결제 쪽은 지금 속도로는 두 개가 한계라고 답합니다. 왜냐고 물으면 태오는 최근 세 번의 결제 관련 수정에 각각 며칠이 걸렸는지, 그중 실제 기능을 만든 시간과 기존 코드를 이해하는 데 쓴 시간이 어떻게 갈렸는지를 가져옵니다. 기능 하나에 5일이 들었고 그중 3일이 읽는 데 갔다는 식입니다.

규원이 여기서 묻는 것은 하나입니다. 지금 이틀을 쓰면 다음 분기에 며칠을 벌어 오느냐입니다. 답이 숫자로 나오지 않으면 정리 일정은 대개 뒤로 밀립니다. 그래서 태오는 수정마다 걸린 날짜와 그 이유를 짧게 적어 두기 시작했습니다. 근거가 기록으로 남은 뒤부터 같은 요청이 회의에서 훨씬 빨리 통과합니다.

지현은 이 숫자를 일정에 반영합니다. 코드 품질이 나쁜 영역에 걸린 기능은 같은 크기여도 더 오래 잡고, 정리 작업을 기능 사이에 끼워 넣습니다. 태오네 팀은 별도 일정을 받지 못한 영역에서는 손댄 자리만 조금씩 낫게 두는 방식으로 버팁니다. 반년쯤 지나면 자주 고치는 파일부터 눈에 띄게 읽기 좋아지고, 아무도 안 건드리는 파일은 그대로 남습니다. 자주 건드리는 곳이 먼저 좋아지는 것이 이 방식의 의도한 결과입니다.

흔한 오해

코드 품질을 시간이 남을 때 하는 일로 여기는 오해가 가장 흔합니다. 정리를 아무리 해도 화면에서 달라지는 것이 없고 고객이 알아채지도 못하니, 급한 일이 끝난 다음에 해도 되는 일처럼 보입니다. 실제로는 다음 기능이 며칠 만에 나갈지를 정하는 변수입니다. 같은 크기의 기능이 어떤 영역에서는 이틀이고 어떤 영역에서는 일주일인 차이가 거기서 납니다. 이 오해를 그대로 두면 분기마다 같은 일에 드는 시간이 조금씩 늘고, 어느 시점에 개발팀에서 처음부터 새로 만드는 편이 빠르다는 말이 나옵니다. 그 제안이 받아들여지면 몇 달 동안 새 기능이 하나도 나가지 않고, 새로 만든 쪽도 같은 습관으로 쓰이면 2년 뒤에 같은 대화가 반복됩니다. 미루는 동안 값이 사라지는 것이 아니라 이자가 붙어 자란다는 점에서, 이 오해는 급한 일을 먼저 하는 판단이 아니라 더 비싼 시점으로 일을 옮기는 판단에 가깝습니다.

품질은 높을수록 좋다고 보는 것도 자주 나옵니다. 품질이라는 말 자체가 많을수록 좋게 들리니 자연스러운 오해입니다. 하지만 코드마다 수명이 다릅니다. 될지 안 될지 확인하려고 일주일 쓰고 버릴 실험용 화면과, 3년 동안 돈이 오갈 결제 코드에 같은 잣대를 대면 양쪽 다 어긋납니다. 앞쪽은 확인이 늦어지고 뒤쪽은 위험한 채로 남습니다. 이 오해를 그대로 두면 팀은 검증되지 않은 아이디어에 완성도를 들이느라 배우는 속도를 잃거나, 반대로 실험실 기준을 그대로 들고 오래 갈 코드에 적용합니다. 실제로 정할 것은 품질의 높낮이가 아니라 이 코드가 얼마나 오래 살 것인지이고, 수명이 정해지면 어디까지 다듬을지는 따라 나옵니다.

같이 보면 좋은 페이지

  • 엔지니어링

    코드 품질이 기술 조직의 어느 갈래에 얹힌 일인지 먼저 봅니다

  • 리팩터링

    나빠진 코드를 실제로 되돌리는 작업이라 다음은 여기입니다

하위 용어

마지막 업데이트 2026-09-16