# [[Static Code Analysis (정적 코드 분석기)]]

## 📌 Brief Summary
정적 코드 분석기(또는 정적 프로그램 분석/린팅)는 소프트웨어 코드를 직접 실행하지 않고 평가하여 일반적인 프로그래밍 결함과 코드 품질 문제를 탐지하는 기술 및 도구입니다[1]. 유효하지만 표준 이하인 프로그램의 문제를 찾아내며, 지나치게 긴 함수나 중복 코드 같은 구조적 약점을 식별하여 개발자가 소프트웨어 개발 초기에 리팩토링을 수행할 수 있도록 돕습니다[1-3].

## 📖 Core 무Content
- **목적 및 역할:** 정적 분석기는 코드를 실행하지 않은 상태에서 분석을 수행하여 결함을 조기에 발견하고 코드 품질을 개선합니다[1]. 덜 엄격한 인터프리터 언어에서는 '린팅(linting)'이라고도 불리며, 문법적으로는 유효하지만 구조적으로는 표준에 미치지 못하는 프로그램의 문제점을 찾아냅니다[2].
- **리팩토링 후보 식별:** 이 도구들은 인수가 너무 많거나 길이가 지나치게 긴 함수와 같은 구조적 약점을 찾아내어 리팩토링의 후보를 제시합니다[3]. 또한 중복을 암시할 수 있는 구조적 유사성을 감지하는 데에도 사용됩니다[3].
- **주요 분석 기법:** 정적 프로그램 분석에는 데이터 및 제어 의존성을 명시적으로 표현하는 프로그램 의존성 그래프(Program dependence graph), PDG 간의 프로시저 호출을 나타내는 시스템 의존성 그래프(System dependence graph), 순환 복잡도 분석(Cyclomatic complexity analysis), 초기 상태를 리버스 엔지니어링하여 내부 의존성을 파악하는 소프트웨어 인텔리전스 등이 포함됩니다[2].
- **도구 및 지원:** 다중 언어를 지원하는 Codacy와 오픈소스 PMD, Java용 JArchitect, .NET용 NDepend, Ruby용 RuboCop 린터 및 포매터 등 다양한 정적 코드 분석기가 존재합니다[1]. 또한 마이크로소프트의 MaX와 같은 의존성 분석 도구는 함수 및 바이너리 모듈 수준의 시스템 전체 의존성 그래프를 생성하여 제거해야 할 유해한 의존성을 식별하는 데 사용됩니다[4-6].

## ⚖️ Trade-offs & Caveats
- **코드 의미(Meaning) 이해의 한계:** 정적 분석 도구는 C/C++ 프로그램에 lint를 적용하는 것과 유사하게 구조적인 분석을 수행하지만, 프로그램의 실제 의미나 맥락을 이해할 만큼 지능적이지는 않습니다[7]. 
- **개발자의 자율적 판단 요구:** 정적 분석 도구가 구조적 분석을 바탕으로 여러 가지 리팩토링 제안을 하더라도, 그중 일부만이 실제로 시스템에 적용해야 할 의미 있는 변경사항일 수 있습니다[7]. 따라서 도구의 제안을 무조건적으로 맹신하여 적용하기보다는 개발자가 직접 개입하여(make the call) 리팩토링 여부와 방향을 최종적으로 판단해야 하는 제약이 따릅니다[7].

## 🔗 Knowledge Connections

### Related Concepts

#### [구조적 결함 및 품질 (Structural Flaws & Quality)]
- [[Code Smell]]
  - 연결 이유: 정적 분석 도구는 과도한 인수, 거대 함수, 중복 코드 등과 같은 코드 스멜을 기계적으로 감지하여 리팩토링의 대상을 찾아내기 때문입니다[3].
  - 이 개념을 통해 더 깊게 이해할 수 있는 부분: 정적 분석기가 어떤 비정상적인 패턴을 찾아내려 하는지 그 본질적 기준을 이해할 수 있습니다.

#### [분석 및 측정 기법 (Analysis & Measurement Techniques)]
- [[Cyclomatic Complexity]]
  - 연결 이유: 정적 분석에서 활용되는 대표적인 구조 분석 기법 중 하나로 소스에서 명시적으로 언급되었습니다[2].
  - 이 개념을 통해 더 깊게 이해할 수 있는 부분: 조건문의 중첩이나 로직의 얽힘이 어떻게 수치화되며, 이것이 왜 리팩토링(예: 조건문 단순화)의 대상이 되는지 이해할 수 있습니다.
- [[Program Dependence Graph]]
  - 연결 이유: 정적 분석기가 프로그램 내 데이터 및 제어 의존성을 명시적으로 표현하는 수단이기 때문입니다[2].
  - 이 개념을 통해 더 깊게 이해할 수 있는 부분: 변수와 함수가 내부적으로 어떻게 결합되어 있는지 시각화함으로써 '함수 추출'이나 '변수 이동' 같은 리팩토링의 영향을 깊이 파악할 수 있습니다.

#### [리팩토링 실행 및 워크플로우 (Refactoring Execution)]
- [[Automated Refactoring Tools]]
  - 연결 이유: 정적 분석이 문제를 식별(탐지)하는 역할을 한다면, 자동화된 리팩토링 도구(예: Refactoring Browser)는 발견된 문제를 코드를 깨뜨리지 않고 실제로 안전하게 변환(해결)하는 역할을 수행하기 때문입니다[8, 9].
  - 이 개념을 통해 더 깊게 이해할 수 있는 부분: 코드 문제의 자동 진단에서부터 안전한 자동 수정까지 이어지는 최신 개발 환경의 파이프라인을 이해할 수 있습니다.

### Deeper Research Questions
- 정적 분석 도구가 탐지한 수많은 구조적 약점 중에서 개발자가 실제로 리팩토링을 수행해야 하는 코드를 선별하는 기준과 우선순위 결정 방식은 무엇인가?
- 프로그램 의존성 그래프(PDG)와 시스템 의존성 그래프(SDG)는 거대한 레거시 시스템을 모듈화하기 위한 리팩토링 계획 수립에 구체적으로 어떻게 활용되는가?
- 정적 코드 분석기로는 식별할 수 없지만 테스트 코드나 동적 분석을 통해서만 발견할 수 있는 런타임 코드 스멜이나 설계 결함에는 어떤 것들이 있는가?
- 마이크로소프트의 MaX와 같이 함수 수준의 의존성을 추출하는 정적 분석 도구는 시스템 전체의 '계층형 아키텍처(Layered Architecture)' 규칙을 강제하는 데 어떠한 원리로 기여하는가?
- 동적 타입 언어(예: JavaScript, Ruby)에서 사용되는 린터(Linter)와 정적 타입 언어(예: Java, C#)의 정적 분석기 간에는 결함 감지 및 리팩토링 제안 수준에 있어 어떤 기술적 한계와 차이가 있는가?

### Practical Application Contexts
- **Implementation:** 개발자는 코드를 작성하는 동안 IDE와 통합된 정적 분석기(또는 린터)를 활용하여 긴 함수나 포맷 오류 같은 코드 스멜을 실시간으로 감지하고 즉각적으로 작은 단위의 리팩토링을 수행할 수 있습니다.
- **System Design:** 아키텍트는 MaX와 같은 의존성 추출 도구를 사용하여 바이너리 혹은 모듈 수준의 의존성 그래프를 생성하고, 시스템 내에 유해하게 꼬여있는 의존성(의존성 순환 등)을 찾아내어 시스템 재설계 및 대규모 리팩토링 계획을 수립합니다.
- **Operation / Maintenance:** CI/CD 파이프라인에 정적 분석 도구(PMD, Codacy 등)를 통합함으로써 표준에 미치지 못하거나 구조적 약점이 포함된 코드가 병합되는 것을 방지하고, 유지보수 단계에서 기술 부채가 축적되는 것을 시스템적으로 차단합니다.
- **Learning Path:** 리팩토링의 기본 개념과 코드 스멜의 종류를 학습한 후, 정적 분석 도구를 프로젝트에 적용하여 본인의 코드에 어떤 스멜이 존재하는지 확인하고, 도구가 제시하는 경고를 해결하는 방식으로 리팩토링 훈련을 진행합니다.
- **My Project Relevance:** 현재 관리 중인 프로젝트 코드베이스에서 복잡하거나 장황한 클래스/함수를 객관적인 수치와 지표로 색인해 내기 위해 정적 코드 분석기를 도입하여 리팩토링 대상을 선정할 수 있습니다.

### Adjacent Topics
- [[Technical Debt]]
  - 확장 방향: 정적 코드 분석기가 지속적으로 탐지하는 프로그래밍 결함과 스멜을 제때 리팩토링하지 않고 방치했을 때 누적되는 소프트웨어의 중장기적 개발/유지보수 비용(기술 부채) 문제로 이해를 확장할 수 있습니다.

---
*Last updated: 2026-05-03*