IT

하드코딩 상수 추출이 개발 생산성과 버그 예방에 직결되는 이유

AI 자동화 실무 2026. 7. 26. 05:20
SMALL

하드코딩된 값을 상수로 추출하는 가장 큰 이유는 코드의 의도를 명확히 하고 변경에 유연하게 대응하기 위해서입니다. 소스 코드 곳곳에 흩어진 숫자나 문자열은 시간이 흐를수록 그 의미를 잃어버리며, 단 한 번의 수정만으로도 시스템 전체에 예기치 못한 사이드 이펙트를 일으킬 위험이 큽니다.

처음 코드를 작성할 때는 '나중에 고치면 되겠지' 혹은 '이 값은 절대 안 변해'라고 생각하기 쉽습니다. 하지만 비즈니스 로직이 복잡해지고 협업 인원이 늘어날수록, 맥락 없는 숫자(Magic Number)와 문자열은 동료 개발자뿐만 아니라 미래의 자기 자신에게도 커다란 부채가 됩니다.

이 글에서는 단순히 코드를 깔끔하게 만드는 수준을 넘어, 왜 실무에서 상수 추출을 필수적인 리팩토링 단계로 간주하는지 살펴보겠습니다. 특히 어떤 값을 상수로 빼야 할지 고민되는 지점과 흔히 저지르는 실수들을 함께 짚어보려 합니다.

본격적인 내용에 앞서, 이 주제는 소프트웨어의 가독성과 유지보수성을 높이는 '클린 코드'의 핵심 원칙과 맞닿아 있습니다. 코드의 구조를 설계하는 상위 개념을 먼저 이해하고 싶다면 프로그래밍 설계 원칙에 관한 글을 함께 참고하는 것이 좋습니다.

하드코딩 상수 추출 대표 이미지
하드코딩 상수 추출 주제를 읽기 전에 먼저 보면 좋은 대표 이미지 · 핵심 포인트: 왜 필요한지, 언제 추출할지, 장점

핵심 내용 먼저 보기

핵심 키워드 하드코딩 상수 추출 · 연관 검색어 하드코딩 상수 추출, 매직 넘버, 리팩토링, 클린 코드, 코드 가독성

의미를 알 수 없는 '매직 넘버'가 프로젝트를 망치는 과정

코드 중간에 갑자기 등장하는 숫자 86400이나 문자열 "PENDING"을 마주했을 때, 우리는 이를 '매직 넘버' 또는 '매직 스트링'이라고 부릅니다. 작성 당시에는 하루를 초로 환산한 값이라는 것을 알 수 있지만, 몇 달 뒤에 이 코드를 다시 보면 왜 이 숫자가 여기에 있는지, 다른 곳에서 쓰이는 86400과 같은 의미인지 확신할 수 없게 됩니다.

이런 하드코딩이 위험한 진짜 이유는 수정의 범위가 불분명해지기 때문입니다. 예를 들어 서비스 정책이 바뀌어 특정 제한 수치를 변경해야 할 때, 프로젝트 전체에서 해당 숫자를 검색해 일일이 수정해야 합니다. 이 과정에서 실수로 하나라도 누락하거나, 의미가 다른 동일한 숫자를 잘못 수정하면 치명적인 런타임 오류로 이어집니다.

상수로 추출할 것과 그대로 둘 것을 구분하는 판단 기준

모든 숫자와 문자를 상수로 만들 필요는 없습니다. 오히려 과도한 상수화는 코드를 읽는 흐름을 방해할 수 있습니다. 실무적인 판단 기준은 '이 값이 비즈니스 로직의 정책을 담고 있는가?''중복되어 사용되는가?'입니다. 예를 들어 루프의 시작점인 0이나 단순히 한 칸을 띄우기 위한 공백은 상수로 추출할 실익이 적습니다.

반면, API 타임아웃 시간, 최대 재시도 횟수, 특정 상태 값, 세율 계산식에 들어가는 수치 등은 반드시 상수로 관리해야 합니다. 특히 해당 값이 변경되었을 때 비즈니스 규칙이 바뀐다고 판단된다면, 그 값은 코드 깊숙한 곳이 아니라 설정 파일이나 클래스 상단에 이름을 가진 상수로 존재해야 마땅합니다.

단순 치환을 넘어선 상수화의 실무적 이점

상수 추출은 컴파일 타임의 체크를 가능하게 하여 안정성을 높여줍니다. 문자열을 직접 입력하다 발생하는 오타는 런타임에야 발견되지만, 상수를 사용하면 IDE의 자동 완성 기능을 활용할 수 있고 오타 발생 시 컴파일 에러가 발생하여 즉시 수정이 가능합니다. 이는 대규모 프로젝트에서 디버깅 시간을 획기적으로 줄여주는 요소입니다.

또한, 테스트 코드 작성이 훨씬 수월해집니다. 테스트 환경과 운영 환경에서 서로 다른 값을 적용해야 할 때, 하드코딩된 코드는 수정이 불가능에 가깝지만 상수로 분리된 코드는 환경 설정(Configuration)에 따라 유연하게 값을 주입할 수 있습니다. 결과적으로 코드의 결합도는 낮아지고 응집도는 높아지는 효과를 얻게 됩니다.

이름 짓기에서 흔히 범하는 실수와 개선 방향

가장 흔한 실수는 값 자체를 이름으로 쓰는 것입니다. const TEN = 10; 같은 선언은 아무런 정보를 주지 못합니다. 상수의 이름은 '무엇인가'가 아니라 '왜 존재하는가'를 설명해야 합니다. TEN보다는 MAX_LOGIN_ATTEMPTS가 훨씬 좋은 이름입니다. 값이 10에서 20으로 바뀌더라도 변수명을 바꿀 필요가 없기 때문입니다.

또한, 상수의 범위를 고려하지 않고 무조건 전역(Global)으로 선언하는 것도 지양해야 합니다. 특정 클래스나 함수 내부에서만 의미가 있는 값이라면 해당 스코프 안으로 제한하는 것이 좋습니다. 무분별한 전역 상수는 네임스페이스를 오염시키고, 나중에 어떤 상수가 어디서 쓰이는지 파악하기 어렵게 만듭니다.

결국 하드코딩을 상수로 추출하는 작업은 단순히 코드를 예쁘게 만드는 것이 아니라, 소프트웨어의 생명력을 연장하는 행위입니다. 지금 당장은 1초면 쓸 수 있는 숫자가 나중에는 몇 시간의 디버깅과 수천 줄의 코드 수정을 요구하는 부메랑이 되어 돌아올 수 있음을 기억해야 합니다.

작은 습관이 코드의 질을 결정합니다. 새로운 기능을 구현한 뒤에는 반드시 코드를 다시 훑으며 의미가 모호한 리터럴 값이 없는지 확인해 보세요. 적절한 이름을 가진 상수는 그 자체로 훌륭한 문서 역할을 수행하며, 팀원들 간의 커뮤니케이션 비용을 낮춰줄 것입니다.

이러한 리팩토링 과정에 익숙해졌다면, 다음 단계로는 객체 지향 설계에서의 상태 관리나 설정 정보를 외부 파일로 분리하는 전략에 대해 알아보는 것을 추천합니다. 코드의 가독성을 높이는 변수 명명 규칙이나 함수의 분리 원칙에 대해서도 함께 학습하면 더욱 견고한 코드를 작성할 수 있습니다.

자주 묻는 질문

단 한 번만 사용되는 값도 상수로 추출해야 하나요?

네, 그렇습니다. 사용 횟수보다 중요한 것은 '의미 전달'입니다. 단 한 번 쓰이더라도 그 값이 비즈니스 로직에서 특정한 의미를 가진다면, 이름을 가진 상수로 추출하여 코드의 가독성을 높이는 것이 좋습니다.

상수 이름을 지을 때 가장 주의할 점은 무엇인가요?

값의 내용을 이름에 담지 말고, 그 값이 수행하는 역할을 이름에 담으세요. 예를 들어 'LIMIT_5'가 아니라 'MAX_USER_COUNT'라고 지어야 나중에 제한 수치가 바뀌어도 이름과 값 사이의 모순이 생기지 않습니다.

상수를 별도의 파일로 관리하는 것이 무조건 좋은가요?

프로젝트 규모에 따라 다릅니다. 여러 모듈에서 공통으로 쓰이는 설정값은 별도 파일(예: constants.js, config.yaml)로 관리하는 것이 좋지만, 특정 클래스 내부에서만 쓰이는 상수는 해당 클래스 내부에 정의하는 것이 응집도 측면에서 더 유리합니다.


해시태그

#하드코딩상수추출 #매직넘버 #리팩토링 #클린코드 #코드가독성 #유지보수

LIST