코드 스멜: 무엇이며 기술 부채와 어떤 관련이 있을까요?

코드 스멜: 무엇이며 기술 부채와 어떤 관련이 있을까요?

코드 스멜은 버그가 아닙니다. 버그가 있는 프로그램은 충돌하거나, 잘못된 결과를 반환하거나, 테스트에 실패합니다. 코드 스멜이 있는 프로그램은 수년 동안 완벽하게 작동할 수 있지만, 모든 변경 작업은 필요 이상으로 많은 비용을 초래하고, 새로운 기능을 추가할 때마다 예상치 못한 위험이 따르며, 리팩토링을 시도할 때마다 아무도 몰랐던 의존성이 드러납니다. 코드 스멜은 미래의 문제를 예측하는 코드의 구조적 특징입니다. 당장 오류를 발생시키지는 않지만, 향후 모든 변경 작업을 필요 이상으로 어렵고, 느리고, 위험하게 만듭니다.

이 용어는 마틴 파울러와 켄트 벡이 파울러의 저서 『리팩토링: 기존 코드 설계 개선(Refactoring: Improving the Design of Existing Code )』(1999)에서 널리 알려졌으며, 이 책에서는 22가지 코드 스멜을 분류하고 각각에 해당하는 리팩토링 기법을 제시했습니다. 이 목록은 현재까지도 표준 참고 자료로 자리 잡고 있으며, 파울러가 명명한 코드 스멜(예: 긴 메서드, 갓 클래스, 중복 코드, 기능 선입견, 발산적 변경, 무분별한 코드 수정)은 오늘날 SonarQube 규칙 세트, 정적 분석 도구, 그리고 업계 전반의 코드 검토 체크리스트에 등장합니다.

코드 냄새 정리

SMART TS XL 복잡한 시스템 전반에서 이를 매핑하고 수정하는 데 도움이 됩니다.

더 많은 정보

코드 스멜이란 무엇일까요?

코드 스멜이란 소스 코드의 표면적인 특징으로, 더 깊은 구조적 또는 설계상의 문제를 암시하는 현상입니다. 코드는 컴파일되고 테스트를 통과하며 올바른 출력을 생성하지만, 구조적인 문제로 인해 읽기, 확장 또는 안전한 수정이 어려워집니다. 파울러는 코드 스멜을 "시스템의 더 깊은 문제와 관련된 표면적인 징후"라고 정의했습니다.

코드 스멜은 구문 오류나 어설션 실패와 같은 의미의 위반 사항이 아닙니다. 숙련된 개발자라면 당장 눈에 띄는 오류가 없더라도 코드 스멜을 경고 신호로 인식합니다. 문제는 이러한 코드 스멜이 누적된다는 점입니다. 10,000만 줄짜리 코드베이스에서 긴 메서드 하나는 사소한 불편함일 수 있지만, 수백 개의 긴 메서드, 수십 개의 모듈에 흩어져 있는 중복된 로직, 그리고 의존성 그래프의 중심에 자리 잡은 '갓 클래스(God Class)'는 안전하게 변경하기가 매우 어려운 시스템을 만듭니다.

코드 스멜 vs. 버그 vs. 기술 부채

이 세 가지 개념은 서로 관련되어 있지만 구별되는 개념이며, 이를 혼동하면 우선순위 설정에 오류가 발생합니다.

Concept정의즉각적인 실패?찾는 방법
곤충잘못된 동작을 유발하는 코드네, 테스트가 실패하고 사용자들이 오류를 보고합니다.테스트, 모니터링, 오류 로그
코드 냄새미래 문제를 예측하는 구조적 패턴아니요, 코드는 정상적으로 실행됩니다.코드 검토, 정적 분석
기술적 부채과거의 편법과 잘못된 결정으로 인한 누적 비용아니요, 하지만 시간이 지남에 따라 누적됩니다.메트릭, 복잡성 분석, 리팩토링 노력 예측

코드 스멜은 기술 부채가 축적되는 메커니즘입니다. 코드베이스에 추가되는 각 긴 메서드는 기술 부채의 단위가 되며, 그 이자 비용은 미래의 모든 개발자가 해당 메서드를 이해하는 데 추가로 소요하는 시간과, 향후 모든 변경 사항이 해당 메서드의 규모로 인한 부작용을 피하는 데 소요하는 시간입니다.

SonarQube에서 코드 스멜이란 무엇인가요?

SonarQube는 코드 문제를 버그(명백히 잘못된 코드), 취약점(보안 문제), 코드 스멜 (유지보수성 문제)의 세 가지 범주로 분류합니다. SonarQube의 코드 스멜은 Fowler의 분류 체계에 직접적으로 대응하며, 긴 메서드(설정 가능한 줄 수 임계값 초과), 중복 코드 블록, 과도한 매개변수, 복잡한 인지 복잡성 점수, 오류 처리 누락, 아키텍처 결합 위반 등에 대한 규칙을 포함합니다. SonarQube의 코드 스멜 규칙은 Fowler의 원래 분류 체계를 자동화하여 적용한 업계에서 가장 널리 사용되는 방식입니다.

마틴 파울러의 코드 스멜: 고전적 분류 체계

파울러가 범주별로 정리한 22가지 코드 스멜은 여전히 ​​표준 참고 자료로 사용되고 있습니다. 모든 주요 정적 분석 도구의 규칙 세트는 이 분류 체계에서 파생되었습니다.

카테고리 코드 냄새
블로터스코드가 너무 커져서 다루기 어려워졌습니다.긴 메서드, 큰 클래스, 기본 요소에 대한 집착, 긴 매개변수 목록, 데이터 덩어리
객체지향 프로그래밍 남용자객체지향 원칙의 오용switch 문, 임시 필드, 유산 거부, 다른 인터페이스를 가진 대체 클래스
변화 방지 요인변화를 어렵게 만든다발산적 변화, 산탄총 수술, 병렬적 상속 계층 구조
소모품불필요한 코드주석(과도함), 중복 코드, 게으른 클래스, 데이터 클래스, 사용되지 않는 코드, 추측에 기반한 일반화
커플러과도한 결합외모에 대한 질투, 부적절한 친밀감, 메시지 연쇄, 중개인

어떤 유형의 코드 냄새가 어떤 범주에 속하는지 이해하면 개선 우선순위를 정하는 데 도움이 됩니다. 코드 비대화 요소(Bloator)와 변경 방지 요소(Change Preventer)는 리팩토링 비용 증가와 직접적인 관련이 있으며, 코드 결합 요소(Coupler)는 아키텍처 취약성과 직접적인 관련이 있습니다. 불필요한 요소(Dispensables)는 제거하기 가장 안전한 요소입니다.

가장 흔한 코드 스멜: 빠른 참조

코드 스멜어떻게 생겼는지주요 위험
중복 코드동일한 논리가 여러 곳에서 나타납니다.버그 수정은 모든 곳에 적용해야 합니다. 시간이 지남에 따라 복사본들이 서로 달라지기 때문입니다.
긴 방법여러 가지 책임을 포함하는 20~30줄 이상의 메서드인지 부하가 ​​높아 개별 행동을 테스트하기 어렵습니다.
갓 클래스 / 대규모 클래스모든 것을 다 하는 한 수업모든 기능 변경은 동일한 클래스에 영향을 미치므로 병합 충돌 및 취약성이 발생합니다.
긴 매개변수 목록매개변수가 4개 이상인 메서드잘못된 값을 전달하기 쉽고, 호출 지점을 읽기 어렵습니다.
피처 엔비다른 클래스의 데이터를 자신의 데이터보다 더 많이 사용하는 메서드결합도가 높아서 한 클래스의 변경 사항이 다른 클래스에 영향을 미칩니다.
발산적 변화여러 가지 이유로 수정된 클래스개인 책임 원칙 위반; 예측 불가능한 부작용
산탄총 수술하나의 변경 사항으로 인해 여러 클래스에 걸쳐 수정이 필요합니다.변경 비용이 높고, 발생 사례를 놓치기 쉽습니다.
데드 코드호출되거나 도달되지 않는 코드개발자들을 혼란스럽게 하고, 수년에 걸쳐 누적되며, 마이그레이션을 복잡하게 만듭니다.
원시적 집착도메인 객체 대신 기본 데이터 유형(문자열, 정수) 사용검증 자료가 여기저기 흩어져 있고, 표현력이 부족합니다.
데이터 덩어리동일한 필드 그룹이 반복적으로 함께 전달되었습니다.도메인 객체여야 합니다. 추상화가 누락되었음을 나타냅니다.
추측적 일반화미래의 필요를 상상하여 작성된 코드불필요한 복잡성일 뿐, 왜 필요한지 아무도 이해하지 못한다.
일관되지 않은 오류 처리조용한 캐치, 다양한 예외 처리 전략오류가 감지되지 않고, 디버깅에 훨씬 더 많은 시간이 소요됩니다.

코드 스멜 정의 및 예시

중복 코드

대규모 시스템에서 가장 흔하고 비용이 많이 드는 코드 스멜은 바로 중복입니다. 중복은 복사 붙여넣기 개발, 시간 압박, 그리고 같은 문제를 독립적으로 해결하는 팀들의 사일로 현상에서 발생합니다. 그 즉각적인 결과는 유지보수 비용 증가로 이어지는데, 공유 로직에 대한 모든 변경 사항은 모든 복제본에 적용되어야 합니다.

자바

// ServiceA -- discount calculation
double calculateDiscount(double amount) {
    if (amount > 1000) return amount * 0.1;
    return 0;
}

// ServiceB -- same logic, copied and forgotten
double computeDiscount(double value) {
    if (value > 1000) return value * 0.1;
    return 0;
}

비즈니스 규칙이 변경될 때(임계값이 1500으로, 비율이 12%로 변경될 때), 한 모듈은 업데이트되지만 다른 모듈은 업데이트되지 않습니다. 이로 인해 두 모듈이 기본적인 비즈니스 로직에서 서로 다른 값을 갖게 되고, 이러한 불일치는 테스트 단계가 아닌 운영 환경 감사 중에 드러납니다.

해결 방법 : 공통 로직을 호출하는 두 곳 모두 참조할 수 있는 단일 함수, 유틸리티 클래스 또는 공유 라이브러리로 추출합니다.

긴 방법

시간이 흐르면서 본래의 목적을 넘어 추가적인 책임을 떠맡게 된 방법론. 200줄짜리 방법론을 읽는 인지 부하는 10줄짜리 방법론 20개를 읽는 것과 양적으로만 다른 것이 아니라 질적으로도 다르다. 긴 방법론은 너무 많은 기능을 개별적으로 검증하기 어렵기 때문에 검증하기 어렵고, 읽는 사람이 전체 실행 맥락을 작업 기억에 유지해야 하므로 이해하기도 어렵다.

탐지 임계값 : 20~30줄 이상의 메서드는 검토가 필요하며, 50줄 이상일 경우 거의 항상 리팩토링이 필요합니다. COBOL에서는 100개 이상의 문장으로 구성된 단락이 이에 해당합니다.

파이썬

class OrderProcessor:
    def process_order(self, order):
        # Validate order -- 40 lines
        # Calculate discounts -- 30 lines
        # Update inventory -- 25 lines
        # Send notification emails -- 20 lines
        # Generate invoice -- 35 lines
        # 150+ lines total
        pass

이 메서드 내의 각 책임은 별도의 클래스 또는 함수로 분리되어야 합니다. 이를 하나로 묶으면 향후 송장 발행, 재고 관리 또는 알림 기능 업데이트 시 전체 주문 처리 흐름이 불안정해질 위험이 있습니다.

갓 클래스

여러 영역에 걸쳐 책임을 분산시켜 단일 책임 원칙을 심각하게 위반하는 클래스는 코드베이스의 중심이 됩니다. 모든 것이 이 클래스에 의존하며, 이 클래스의 어떤 부분을 변경하더라도 그 클래스에 대한 모든 것을 이해해야 합니다.

탐지 신호 : 20~30개 이상의 공개 메서드를 가진 클래스이거나, 이름에 "Manager", "Processor", "Handler", "Utils" 또는 "Helper"라는 단어가 여러 관련 없는 도메인에 적용된 클래스.

발산적 변화

이 클래스는 서로 관련 없는 여러 가지 이유로 수정됩니다. 데이터베이스 스키마가 변경될 때마다, 가격 책정 규칙이 변경될 때마다, 알림 형식이 변경될 때마다 이 클래스를 수정해야 합니다. 이 클래스는 너무 많은 책임을 지고 있으므로 분리해야 합니다.

정의 : 여러 가지 이유로 끊임없이 변화하는 클래스. 샷건 수술의 반대 개념.

산탄총 수술

개념적인 한 가지 변경 사항으로 인해 여러 클래스에 걸쳐 수정이 필요합니다. 세율을 변경하려면 백엔드 계산, 프런트엔드 유효성 검사, 데이터베이스 트리거, 배치 작업 및 보고 쿼리 등 다섯 군데를 수정해야 합니다. 이 중 하나라도 누락되면 일관성 없는 동작이 발생합니다.

SQL

-- Tax logic duplicated across queries
SELECT amount * 0.05 FROM invoices;
SELECT amount * 0.05 FROM payments;
SELECT amount * 0.05 FROM reports;

0.05를 0.07로 변경하려면 이제 SQL 파일, 저장 프로시저 및 애플리케이션 코드 전체에서 해당 값을 모두 찾아야 합니다.

피처 엔비

메서드 실행 시간이 자신의 클래스보다 다른 클래스의 데이터와 메서드를 더 많이 사용하는 경우, 해당 동작은 다른 클래스에 속해야 할 가능성이 높습니다.

자바

// In ReportGenerator -- envious of Customer's data
double calculateCustomerRating(Customer customer) {
    return customer.getOrderCount() * customer.getAverageOrderValue()
           / customer.getDaysSinceRegistration();
}
// This logic belongs in Customer, not ReportGenerator

데드 코드

저장소에는 존재하지만 프로덕션 환경에서 어떤 실행 경로에서도 호출되지 않는 코드를 데드 코드라고 합니다. 데드 코드는 기능이 제거되거나, 교체되거나, 구조가 재구성되면서 기존 코드를 삭제하지 않고 그대로 남겨두는 경우가 많아 수년에 걸쳐 축적됩니다. 이는 코드 검토 시 혼란을 야기하고, 개발자들이 코드베이스에 적응하는 데 어려움을 느끼게 하며, 마이그레이션 분석을 복잡하게 만들고, 때로는 의도치 않게 다시 활성화되기도 합니다.

Detection System정적 분석 도구에는 SonarQube, Knip(TypeScript/JavaScript용) 등이 포함됩니다. SMART TS XL 코드베이스 전체에서 도달할 수 없는 함수, 호출되지 않은 메서드 및 사용되지 않는 변수를 식별합니다.

DRY 원칙 위반

DRY(Don't Repeat Yourself) 원칙은 시스템 내 모든 정보는 명확하고 모호하지 않은 단일한 표현으로 존재해야 한다는 것입니다. DRY 원칙 위반은 중복 코드, 데이터 덩어리, 그리고 무분별한 코드 수정(Shotgun Surgery)과 같은 문제의 근본 원인입니다. 비즈니스 로직이 여러 곳에 표현되면 필연적으로 표현 방식이 서로 달라지게 됩니다. DRY는 원칙이고, 중복 코드는 DRY 원칙 위반을 나타내는 '냄새'입니다.

파이썬

# DRY violation: same validation logic in three places
def validate_email_in_registration(email):
    return "@" in email and "." in email

def validate_email_in_profile_update(email):
    return "@" in email and "." in email

def validate_email_in_checkout(email):
    return "@" in email and "." in email

# DRY-compliant: one function, three callers
def is_valid_email(email):
    return "@" in email and "." in email

코드 스멜 탐지 임계값: 코드가 언제 문제가 되는가?

코드 스멜 감지에는 측정 가능한 임계값이 필요합니다. 아래는 일반적으로 사용되는 측정 지표와 주의가 필요한 코드 스멜을 나타내는 값입니다.

메트릭무엇을 측정하는가경고 임계값중요 임계값
순환적 복잡성메서드의 결정 분기 수10 위20 위
메서드 길이(줄 수)메서드/함수의 줄 수20 위50 위
매개변수 수메서드가 허용하는 매개변수의 개수4 위7 위
수업 길이클래스의 줄 수200 위500 위
중복률중복된 코드의 비율3 % 이상10 % 이상
인지적 복잡성코드를 이해하기 얼마나 어려운가15 위25 위
구심성 연결(Ca)이 클래스에 의존하는 클래스의 수15 위30 위
원심 결합(Ce)이 수업이 의존하는 수업의 수15 위30 위

이러한 임계값은 SonarQube에서 구성할 수 있으며, 대부분의 정적 분석 플랫폼은 이러한 지표를 기반으로 사용자 지정 규칙을 허용합니다. 임계값이 높은 클래스와 메서드는 최우선 순위 리팩토링 대상입니다. 이들은 향후 결함 발생 가능성이 가장 높고 유지 관리 비용이 가장 많이 드는 구성 요소이기 때문입니다.

코드 스멜 탐지 도구

자동화된 탐지는 대규모 코드베이스에서 코드 스멜을 식별하는 데 있어 유일하게 확장 가능한 접근 방식입니다. 수동 검토는 자동화 도구가 찾아내는 것의 극히 일부만을 잡아낼 뿐이며, 수백만 줄에 달하는 레거시 시스템에는 적용할 수 없습니다.

수단기본 언어무엇을 감지하는가
소나큐브 / 소나클라우드자바, 파이썬, 자바스크립트/텍스트 편집, C# 등풀 파울러 냄새 분류 체계, 보안 취약점, 중복
체크스타일 + PMD자바스타일 위반, 중복, 복잡성 지표
ESLint + typescript-eslint자바 스크립트, TypeScript긴 함수, 복잡한 코드, 사용되지 않는 코드
파일린트 + 라돈Python복잡성, 스타일, 유지보수성 지수
리샤퍼 / 라이더C#중복 코드, 긴 메서드, 결합 문제
클리 피녹Rust에서 흔히 나타나는 관용적 규칙 위반, 즉 코드 스멜(code smell)로 간주되는 일반적인 패턴
코드기후다국어복잡성, 중복, 유지보수성 점수
SMART TS XLCOBOL, JCL, Java, Python, RPG, SQL, .NET언어 간 코드 중복, 사용되지 않는 코드, 결합도, 의존성 변화

Rust 코드의 냄새 주로 관용적인 Rust 패턴을 강제하는 Clippy에 의해 포착됩니다. 가장 흔한 Rust 특유의 악취에는 불필요한 클론 생성, 코드의 오용 등이 있습니다. unwrap() 프로덕션 경로에서, 과도하게 중첩된 일치 표현식 및 값을 반환해야 하는 함수 Result 하지만 그 대신 패닉을 사용하세요.

코드 스멜과 기술 부채: 연관성

기술 부채는 품질을 희생하면서 속도를 우선시했던 과거의 결정으로 인해 누적된 비용입니다. 코드 스멜은 이러한 부채가 코드 구조에 나타나는 메커니즘입니다. 둘 사이의 관계는 직접적입니다. 해결되지 않은 코드 스멜 하나하나가 기술 부채의 단위가 되며, 그에 따른 이자율은 향후 모든 변경 사항에서 해당 스멜을 해결하기 위해 추가로 소요되는 시간입니다.

소프트웨어 변경 관리의 영향 분석 맥락에서 설명했듯이 , 코드 스멜이 나타내는 구조적 문제, 과도한 결합, 중복된 로직, 사용되지 않는 코드의 축적은 모든 변경 사항의 범위를 직접적으로 확대합니다. 왜냐하면 이러한 문제들 때문에 특정 변경 사항이 어떤 부분에 영향을 미칠지 파악하기가 더 어려워지기 때문입니다.

코드 스멜(code smell)을 예로 들어 기술 부채를 설명하겠습니다 . 코드베이스에 40%의 중복이 있다면, 버그 수정 비용은 필요 이상으로 1.4배 증가합니다. 모든 것이 의존하는 핵심 처리 클래스가 '갓 클래스(God Class)'라면, 새로운 기능을 추가할 때마다 해당 클래스 전체를 이해하고 테스트해야 합니다. 오류 처리가 일관성이 없다면, 프로덕션 환경에서 발생하는 모든 장애에 대해 더 많은 조사 시간이 소요됩니다. 오류 신호가 신뢰할 수 없기 때문입니다. 기술 부채는 추상적인 개념이 아니라, 이러한 비효율성이 누적되어 나타나는 총합입니다.

CISQ 연구에 따르면 개발자들은 새로운 기능을 구축하는 대신 기술 부채를 해결하는 데 30~40%의 시간을 소비하는 것으로 일관되게 나타납니다. 코드 스멜 밀도는 누적된 기술 부채의 양을 측정하는 가장 직접적인 지표입니다.

방법 SMART TS XL 엔터프라이즈 규모에서 코드 스멜을 감지합니다.

SonarQube나 Clippy 같은 개별 도구는 단일 언어 내에서 작동합니다. COBOL 프로그램이 Java 서비스에서 읽는 데이터 세트에 데이터를 쓰고, JCL 작업 스트림이 여러 언어로 작성된 프로그램을 호출하며, 동일한 비즈니스 로직이 서로 다른 시대에 작성된 세 가지 시스템에 독립적으로 복제되어 있는 엔터프라이즈 환경에서는 단일 언어 도구로는 전체적인 상황을 파악할 수 없습니다.

SMART TS XL의 정적 코드 분석 이 도구는 환경 내 모든 언어에서 동시에 코드 스멜을 감지합니다. 예를 들어 COBOL 코드북과 Java 유틸리티 클래스 간의 중복 로직, JCL 작업에서 호출되지 않는 RPG 프로그램의 데드 코드, 단일 단락이 50개 단락의 역할을 하는 COBOL 프로그램의 갓 클래스 패턴, 그리고 언어 간 경계에서 일관성이 없는 오류 처리 패턴 등을 찾아냅니다.

애플리케이션 종속성 매핑 기능은 개별 파일 수준 도구로는 파악할 수 없는 아키텍처상의 문제점을 식별합니다. 예를 들어, 어떤 구성 요소가 가장 높은 의존성을 가지며, 변경 시 문제가 발생할 위험이 가장 높은지, 독립적이어야 하는 모듈 간에 순환 종속성이 존재하는지, 그리고 중복된 비즈니스 로직이 서로 다른 시스템에서 독립적으로 유지 관리되었지만 각 복사본이 다른 복사본의 존재를 알지 못하는지 등을 파악할 수 있습니다.

영향 분석 기능을 통해 코드 스멜을 즉시 해결할 수 있습니다. 결합도가 높은 구성 요소를 리팩토링하기 전에 영향 분석을 통해 테스트, 검증 또는 업데이트가 필요한 모든 종속 구성 요소를 열거할 수 있습니다. 이를 통해 대규모의 코드 스멜이 있는 코드베이스에서 팀이 겪는 "리팩토링 마비" 현상을 구조화되고 범위가 명확한 개선 프로그램으로 전환할 수 있으며, 각 변경 사항에는 불확실한 위험이 아닌 명확한 범위가 부여됩니다.

레거시 시스템 현대화 프로그램을 진행하는 팀에게 코드 스멜 분석은 현대화 계획의 기반입니다. 마이그레이션을 시작하기 전에 사용되지 않는 코드를 제거하여 작업 범위를 줄이고, 중복된 로직을 표준 구현으로 통합하며, 결합도가 가장 높은 구성 요소는 (해당 구성 요소에 의존하는 모든 구성 요소가 처리된 후) 마지막에 현대화하고, 핵심 클래스(God Class)는 새로운 언어로 변환하기 전에 분해합니다. 왜냐하면 핵심 클래스를 Java로 변환하면 Java에서도 핵심 클래스가 생성되기 때문입니다.

코드 스멜 해결: 우선순위 프레임워크

모든 코드 스멜이 즉각적인 리팩토링을 필요로 하는 것은 아닙니다. 올바른 접근 방식은 위험 기반 우선순위 설정입니다.

최우선 순위: 변경 빈도가 높은 구성 요소의 코드 스멜. 자주 변경되고 복잡성이나 결합도가 높은 코드는 가장 많은 결함을 발생시킵니다. 이러한 구성 요소는 변경당 비용이 가장 많이 들고 운영 환경에서 가장 많은 문제를 야기합니다. 따라서 이러한 구성 요소를 먼저 수정해야 합니다.

우선순위 2, 아키텍처 경계에서의 코드 냄새. 모든 것이 의존하는 핵심 클래스와 결합도가 높은 컴포넌트는 변경하기 가장 위험하지만, 수정하지 않고 방치할 경우 가장 큰 비용이 발생합니다. 따라서 리팩토링 전에 영향 분석을 가장 신중하게 수행해야 합니다.

우선순위 3, 시스템 경계를 넘나드는 중복 코드. 동일한 비즈니스 로직이 여러 시스템에 존재하는 경우, 모든 시스템에 걸쳐 변경 사항을 동시에 조정해야 합니다. 이러한 중복을 통합하면 조정 오버헤드를 줄이고 코드 불일치를 방지할 수 있습니다.

우선순위 4, 사용되지 않는 코드 제거. 사용되지 않는 코드는 가장 안전하게 처리할 수 있는 범주입니다. 제거해도 동작이 깨지지 않고, 단지 이전에 숨겨져 있던 의존성만 드러낼 뿐입니다. 따라서 마이그레이션이나 변환 작업을 시작하기 전에 제거해야 합니다. 호출되지 않을 코드를 변환하는 데 불필요한 노력을 낭비하지 않도록 하기 위함입니다.

우선순위 5, 위험도가 낮은 영역의 스타일 및 구조적 문제점. 안정적이고 변경 빈도가 낮은 코드에서 긴 메서드와 매개변수 목록은 주변 코드가 다른 이유로 변경되어야 할 때 기회적으로 해결할 수 있으며, 이때 주변의 문제점들도 동시에 리팩토링할 수 있습니다.

코드 스멜을 체계적으로 감지, 측정 및 해결하는 것은, 이미 프로덕션 환경에서 오류를 발생시킨 후에야 대응하는 것이 아니라, 시스템 규모가 커짐에 따라 개발 속도가 점차 느려지는 팀과 지속적인 개발 속도 유지를 보장하는 팀을 구분 짓는 핵심 요소입니다.