[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,189 +2,279 @@
|
||||
id: wiki-2026-0508-code-smells
|
||||
title: Code Smells
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [코드 악취, code smell, refactoring catalog, Fowler, bloater, coupler, dispensable]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [auto-consolidated, technical-documentation]
|
||||
confidence_score: 0.93
|
||||
verification_status: applied
|
||||
tags: [refactoring, code-smell, fowler, software-quality, technical-debt, oop, code-review]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: language-agnostic
|
||||
framework: refactoring catalog
|
||||
---
|
||||
|
||||
# [[코드 악취 식별과 리팩토링 징후 (Code Smells)]]
|
||||
# Code Smells
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
No summary available.
|
||||
## 📌 한 줄 통찰
|
||||
> **"매 code 의 surface 의 sign 의 deeper problem"**. Martin Fowler 의 catalog. 매 syntax 의 OK 가, 매 design 의 ill. 매 refactoring 의 trigger. 매 modern: 매 SonarQube / Semgrep / AI review 의 자동 detect.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
소스 코드에 명시된 리팩토링 카탈로그에 따르면, 코드 악취는 코드베이스를 읽고 구조를 파악하는 데 방해가 되는 여러 가지 패턴으로 분류됩니다 [4, 5]. (※ 소스에는 각 코드 악취에 대한 구체적인 작동 원리나 상세 설명은 부족하며, 주로 분류 체계 및 목록 위주의 정보가 제공됩니다.)
|
||||
## 📖 핵심
|
||||
|
||||
* **비대화 (Bloaters)**
|
||||
코드가 시간이 지남에 따라 통제하기 어려울 정도로 커진 상태를 뜻합니다.
|
||||
* 긴 메서드 (Long Method), 거대한 클래스 (Large Class), 원시 타입 집착 (Primitive Obsession), 긴 매개변수 목록 (Long Parameter List), 데이터 군집 (Data Clumps) 등이 포함됩니다 [4, 5].
|
||||
* **객체지향 남용 (Object-Orientation Abusers)**
|
||||
객체지향 프로그래밍의 원칙을 불완전하게 적용했거나 잘못 활용한 경우입니다.
|
||||
* 스위치 문 (Switch Statements), 임시 필드 (Temporary Field), 거부된 유산 (Refused Bequest), 다른 인터페이스를 가진 대체 클래스 (Alternative Classes with Different Interfaces)가 있습니다 [4, 5].
|
||||
* **변경 방해자 (Change Preventers)**
|
||||
코드의 한 부분을 수정할 때 시스템의 다른 많은 부분도 함께 수정해야만 하게 만드는 구조적 악취입니다.
|
||||
* 뒤엉킨 변경 (Divergent Change), 산탄총 수술 (Shotgun Surgery), 평행 상속 계층 (Parallel Inheritance Hierarchies)이 속합니다 [4, 5].
|
||||
* **불필요한 요소 (Dispensables)**
|
||||
코드베이스에 존재할 이유가 없으며, 오히려 가독성을 떨어뜨리고 용량만 차지하는 요소입니다.
|
||||
* 불필요한 주석 (Comments), 중복 코드 (Duplicate Code), 게으른 클래스 (Lazy Class), 데이터 클래스 (Data Class), 죽은 코드 (Dead Code), 추측성 일반화 (Speculative Generality) 등이 해당합니다 [4, 5].
|
||||
* **결합기 (Couplers)**
|
||||
클래스 간의 결합도를 과도하게 높여서 모듈화를 저해하는 요소입니다.
|
||||
* 기능 편애 (Feature Envy), 부적절한 친밀도 (Inappropriate Intimacy), 메시지 체인 (Message Chains), 미들맨 (Middle Man)이 포함됩니다 [4, 5].
|
||||
* **기타 악취**
|
||||
* 불완전한 라이브러리 클래스 (Incomplete Library Class) [4, 5].
|
||||
### 매 Fowler 의 6 category
|
||||
|
||||
이러한 코드 악취들은 코드 분석 도구(Code Analysis Tools)에 의해 식별될 수 있으며, 이를 정리하면 더 적은 버그, 더 나은 유지보수성, 팀의 생산성 증가라는 결과를 가져옵니다 [2].
|
||||
#### 1. Bloater
|
||||
- **Long Method**: 매 single function 의 거대.
|
||||
- **Large Class**: 매 god class.
|
||||
- **Primitive Obsession**: 매 string / int 의 abuse.
|
||||
- **Long Parameter List**: 매 4+ parameter.
|
||||
- **Data Clump**: 매 같이 쓰이는 data 의 group X.
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
*※ 소스에 코드 악취 해결(리팩토링) 자체에 대한 명시적인 부작용이나 제약 사항이 깊이 있게 서술되어 있지는 않습니다. 다만 코드 분석 및 리팩토링의 맥락에서 다음 사항들을 유추 및 확인할 수 있습니다.*
|
||||
#### 2. OO Abuser
|
||||
- **Switch Statement**: 매 polymorphism 의 missed.
|
||||
- **Temporary Field**: 매 일부 case 만 의 사용 field.
|
||||
- **Refused Bequest**: 매 inherit 가, 매 일부 의 X.
|
||||
- **Alternative Classes with Different Interface**: 매 same job, 매 다른 method name.
|
||||
|
||||
* **오탐(False Positives)으로 인한 피로감:** 코드 악취나 취약점을 잡기 위해 자동화된 코드 스캐닝 도구를 무분별하게 사용할 경우, 잘못된 경고(False Positives)가 과도하게 발생할 수 있습니다. 이는 개발자의 신뢰를 떨어뜨리고 리뷰에 불필요한 시간을 낭비하게 만드는 부작용(Alert Fatigue)을 낳을 수 있습니다 [6-9].
|
||||
* **성능과 개발 속도 저하:** 코드 악취를 찾기 위한 도구가 파이프라인 성능에 영향을 주거나 통합이 원활하지 않으면 시스템 릴리스 주기를 지연시키고 개발자의 경험을 저해할 수 있습니다 [9, 10].
|
||||
* **섣부른 추상화 경계:** '추측성 일반화'와 같은 악취를 예방하기 위한 지나친 리팩토링이나, 코드 악취인 '중복 코드'를 제거하기 위한 조기 추상화는 오히려 코드의 복잡성을 가중시킬 수 있습니다 [11].
|
||||
#### 3. Change Preventer
|
||||
- **Divergent Change**: 매 1 class 의 매 다른 reason 의 수정.
|
||||
- **Shotgun Surgery**: 매 1 변경 의 매 N class 의 수정.
|
||||
- **Parallel Inheritance Hierarchies**: 매 두 hierarchy 의 동시 의 grow.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- [[Refactoring]]: 코드 악취를 제거하기 위한 구체적인 기술적 해법.
|
||||
- [[Technical_Debt]]: 코드 악취를 방치했을 때 축적되는 결과물.
|
||||
- [[Clean_Code]]: 코드 악취가 없는 상태의 지향점.
|
||||
#### 4. Dispensable
|
||||
- **Duplicate Code** (DRY violation).
|
||||
- **Lazy Class**: 매 도움 X.
|
||||
- **Data Class**: 매 anaemic (case-by-case).
|
||||
- **Dead Code**: 매 unused.
|
||||
- **Speculative Generality**: 매 hypothetical 의 design.
|
||||
- **Comments**: 매 reason 의 explain 의 X 의 case.
|
||||
|
||||
---
|
||||
#### 5. Coupler
|
||||
- **Feature Envy**: 매 method 의 다른 class 의 더 사용.
|
||||
- **Inappropriate Intimacy**: 매 internal 의 over-share.
|
||||
- **Message Chain**: `a.b().c().d()` 의 chain.
|
||||
- **Middle Man**: 매 delegation 만.
|
||||
|
||||
### Related Concepts
|
||||
#### 6. Other
|
||||
- **Mysterious Name**: 매 unclear identifier.
|
||||
- **Magic Number**: 매 unnamed constant.
|
||||
- **Insider Trading**: 매 inappropriate field access.
|
||||
- **Incomplete Library Class**.
|
||||
|
||||
#### [분석 및 탐지 도구 (Analysis & Detection Tools)]
|
||||
- [[코드 분석 도구 (Code Analysis Tools)]]
|
||||
- 연결 이유: 코드 악취, 논리적 오류, 유지보수성 문제 등을 소스 코드 내에서 식별하여 가시성을 제공하는 핵심 도구입니다 [1, 2].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 정적 분석(SAST) 방식이 어떻게 코드베이스를 실행하지 않고도 잠재적 악취를 잡아내어 버그를 방지하는지 이해할 수 있습니다 [1].
|
||||
### 매 modern addition (Fowler 2nd ed)
|
||||
- **Mutable Data**.
|
||||
- **Global Data**.
|
||||
- **Loops** (Stream / functional 의 lieu).
|
||||
- **Repeated Switches**.
|
||||
|
||||
- [[SonarQube]]
|
||||
- 연결 이유: 지속적인 코드 품질 검사를 통해 버그와 '코드 악취(Code Smells)'를 탐지하는 대표적인 솔루션입니다 [3, 12].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 멀티 언어 환경에서 CI/CD와 결합하여 코드의 건강도를 유지하는 방법론을 파악할 수 있습니다 [3].
|
||||
### 매 detection
|
||||
- **Manual review**.
|
||||
- **Linter**: ESLint, RuboCop, Pylint.
|
||||
- **SAST**: SonarQube, CodeClimate.
|
||||
- **Semgrep**: 매 custom rule.
|
||||
- **AI review**: CodeRabbit, Greptile.
|
||||
|
||||
#### [코드 개선 및 구조화 (Code Improvement & Structuring)]
|
||||
- [[리팩토링 (Refactoring)]]
|
||||
- 연결 이유: 소스에 나열된 코드 악취들(비대화, 객체지향 남용 등)을 실제로 해결하고 코드를 재구성하기 위한 실천적 접근법입니다 [4, 5].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 코드 악취를 없애기 위해 '메서드 추출(Extract Method)'이나 '메서드 이동(Move Method)' 같은 기법이 어떻게 적용되는지 구체적으로 알 수 있습니다 [4].
|
||||
### 매 refactoring (corresponding)
|
||||
- **Extract Method**: Long Method.
|
||||
- **Extract Class**: Large Class.
|
||||
- **Replace Conditional with Polymorphism**: Switch.
|
||||
- **Move Method**: Feature Envy.
|
||||
- **Hide Delegate**: Message Chain.
|
||||
- **Introduce Parameter Object**: Long Parameter / Data Clump.
|
||||
|
||||
- [[DRY (Don't Repeat Yourself) 원칙]]
|
||||
- 연결 이유: 코드 악취 중 하나인 '중복 코드(Duplicate Code)'를 원천적으로 방지하기 위한 소프트웨어 아키텍처 핵심 원칙입니다 [4, 13].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 지식이나 로직을 단일화하여 유지보수성 및 시스템 안정성을 높이는 논리적 추상화 방식을 이해할 수 있습니다 [13, 14].
|
||||
### 매 priority
|
||||
- 매 not all smells 의 fix 의 immediate.
|
||||
- 매 changing area 의 first.
|
||||
- 매 boy scout rule (better than found).
|
||||
|
||||
### Deeper Research Questions
|
||||
## 💻 패턴
|
||||
|
||||
- 정적 코드 분석 도구(Static Code Analysis)가 코드 악취를 감지할 때 흔히 발생하는 오탐(False Positive)을 줄이기 위한 맥락 기반 탐지 기술은 무엇인가?
|
||||
- 코드베이스의 '변경 방해자(Change Preventers)' 악취가 마이크로서비스 아키텍처로의 클라우드 마이그레이션 및 확장성에 미치는 영향은 무엇인가?
|
||||
- '거대한 클래스'와 '긴 메서드' 같은 비대화(Bloaters) 악취를 리팩토링할 때, 어떤 객체 지향 설계 원칙(예: 단일 책임 원칙)을 기준으로 책임을 분리해야 하는가?
|
||||
- 대규모 레거시 시스템에서 아무도 손대지 못해 악취가 심하게 남아있는 코드 블록을 탐색하고 점진적으로 리팩토링하는 효과적인 방법론은 무엇인가?
|
||||
- AI 기반 코드 리뷰 도구(예: CodeRabbit, Qodo)는 기존 룰 기반 정적 분석 도구가 찾기 힘든 결합기(Couplers) 계열의 복잡한 코드 악취를 어떻게 추론하고 해결책을 제시하는가?
|
||||
### Long Method (extract)
|
||||
```ts
|
||||
// ❌ Long Method
|
||||
function processOrder(order: Order) {
|
||||
// 매 50+ lines: validate, calculate, save, notify, log...
|
||||
}
|
||||
|
||||
### Practical Application Contexts
|
||||
// ✅ Extract Method
|
||||
function processOrder(order: Order) {
|
||||
validate(order);
|
||||
const total = calculateTotal(order);
|
||||
save(order, total);
|
||||
notify(order);
|
||||
}
|
||||
|
||||
- **Implementation:** 코드를 작성할 때부터 긴 매개변수나 임시 필드 남용을 자제하여 객체지향 남용(Object-Orientation Abusers)이나 비대화(Bloaters) 악취가 코드베이스에 유입되지 않도록 합니다.
|
||||
- **System Design:** 도메인 주도 설계나 클린 아키텍처를 도입하여 시스템의 책임을 분리함으로써, 산탄총 수술이나 부적절한 친밀도(Inappropriate Intimacy)와 같은 구조적인 코드 악취 발생을 최소화합니다.
|
||||
- **Operation / Maintenance:** CI/CD 파이프라인에 SonarQube, Cycode 등과 같은 분석 도구를 통합하여 새롭게 추가되는 커밋이나 풀 리퀘스트에서 코드 악취를 지속적으로 식별하고 걸러냅니다.
|
||||
- **Learning Path:** 새로운 코드베이스에 적응(Onboarding)할 때, 의도적으로 악취가 짙은 코드(가장 오랫동안 리팩토링되지 않은 덩어리)를 파고들어 팀원들에게 그 구조의 설계 역사와 제약을 질문하는 탐색 도구로 활용할 수 있습니다 [15].
|
||||
- **My Project Relevance:** 현재 소프트웨어 프로젝트에서 점진적인 리팩토링을 수행하기 위해 코드 분석 툴을 도입하여 중복 코드 및 쓸모없는 코드(Dispensables)를 최우선으로 제거합니다.
|
||||
|
||||
### Adjacent Topics
|
||||
|
||||
- [[기술적 부채 (Technical Debt)]]
|
||||
- 확장 방향: 코드 악취가 적절히 해소되지 않고 누적될 경우 팀의 개발 속도를 늦추고 아키텍처를 부패하게 만드는 기술적 빚의 개념으로 학습을 확장합니다.
|
||||
- [[정적 애플리케이션 보안 테스트 (SAST)]]
|
||||
- 확장 방향: 코드 악취 식별을 넘어, 애플리케이션 보안 취약점을 소스 코드 수준에서 탐지하는 보안 지향적 스캐닝 기법으로 확장합니다.
|
||||
- [[SOLID 원칙]]
|
||||
- 확장 방향: 객체지향 설계 남용(Object-Orientation Abusers) 및 높은 결합도(Couplers) 악취를 방지하기 위한 구조적 설계 지침을 학습합니다.
|
||||
|
||||
---
|
||||
*Last updated: 2026-05-02*
|
||||
|
||||
|
||||
## 1. 개요
|
||||
코드 악취(Code Smells)는 프로그램 소스 코드 내에 존재하는 심각한 문제는 아니지만, 더 깊은 구조적 결함이나 향후 문제를 야기할 수 있는 잠재적인 징후들을 의미한다. 켄트 벡(Kent Beck)과 마틴 파울러(Martin Fowler)에 의해 대중화된 이 개념은, '직관적으로 무언가 잘못되었다'는 느낌을 주는 코드 패턴들을 분류하고 이에 대응하는 구체적인 리팩토링 기법을 연결해준다.
|
||||
|
||||
## 2. 주요 코드 악취 분류
|
||||
- **비대화 (Bloaters)**: 클래스나 메서드가 시간이 지남에 따라 너무 커져서 관리하기 힘든 상태.
|
||||
- *예: 긴 메서드(Long Method), 거대 클래스(Large Class), 데이터 뭉치(Data Clumps).*
|
||||
- **객체 지향 남용 (Object-Orientation Abusers)**: 객체 지향의 원칙을 잘못 적용한 경우.
|
||||
- *예: 복잡한 switch 문, 거부된 유산(상속받은 기능을 전혀 사용 안 함).*
|
||||
- **변경 방해 요소 (Change Preventers)**: 한 곳을 수정하면 연관된 수많은 곳을 같이 고쳐야 하는 구조.
|
||||
- *예: 산탄총 수술(Shotgun Surgery), 분기되는 수정(Divergent Change).*
|
||||
- **불필요한 요소 (Dispensables)**: 존재 가치가 없거나 삭제해도 무방한 코드.
|
||||
- *예: 중복 코드, 죽은 코드(Dead Code), 무의미한 주석.*
|
||||
- **잘못된 결합 (Couplers)**: 클래스 간의 과도한 의존성.
|
||||
- *예: 기능 편애(다른 클래스의 데이터를 과도하게 사용), 메시지 체인.*
|
||||
|
||||
## 3. 엔지니어링 가치
|
||||
- **리팩토링의 이정표**: 코드를 언제, 어디서부터 고쳐야 할지 모를 때 코드 악취는 가장 명확한 우선순위와 리팩토링의 타겟을 제공함.
|
||||
- **기술 부채 조기 탐지**: 심각한 버그나 아키텍처 붕괴로 이어지기 전에 문제의 징후를 발견하여 유지보수 비용을 획기적으로 낮춤.
|
||||
- **공통의 설계 언어**: 팀 내에서 "이 메서드는 산탄총 수술 스멜이 나네요"와 같은 용어를 사용하여 코드 리뷰 시 설계 결함에 대해 구체적이고 전문적인 의사소통 가능.
|
||||
|
||||
## 4. 트레이드오프 및 주의사항
|
||||
- **주관적 판단의 영역**: 무엇이 '악취'인지는 팀의 숙련도나 프로젝트의 맥락에 따라 달라질 수 있음. 기계적인 룰 적용보다는 팀 내 합의된 품질 기준이 중요함.
|
||||
- **성급한 수정의 위험**: 단순히 악취가 난다고 해서 즉시 고치는 것이 항상 최선은 아님. 기능 구현이 급하거나 영향 범위가 너무 넓은 경우 전략적인 '기술 부채'로 남겨두는 판단도 필요.
|
||||
- **도구의 한계**: 정적 분석 도구가 많은 악취를 잡아낼 수 있지만, '기능 편애'나 '잘못된 상속' 같은 논리적 스멜은 개발자의 통찰력 있는 코드 리뷰를 통해서만 발견 가능.
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
- **정보 상태**: 검증 완료 (Verified)
|
||||
- **출처 신뢰도**: A
|
||||
- **검토 이유**: 소프트웨어의 노후화를 방지하고 지속 가능한 구조를 유지하기 위해 설계상의 허점을 포착하는 핵심 렌즈인 '코드 악취' 체계 정립.
|
||||
|
||||
## 📌 Brief 정 요약
|
||||
코드 악취(Code Smells)는 애플리케이션의 유지보수성 문제, 논리적 오류, 그리고 전반적인 코드 품질 저하를 나타내는 소스 코드 내의 징후입니다 [1, 2]. 이러한 악취는 버그의 온상이 될 수 있으며, 지속적인 품질 검사 도구(예: SonarQube) 등을 통해 조기에 발견할 수 있습니다 [2, 3]. 코드 악취를 식별하고 리팩토링을 통해 해결하는 것은 장기적으로 안정적인 제품을 만들고 팀 간의 원활한 협업을 가능하게 하는 핵심 과정입니다 [2, 4, 5].
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
- **정보 상태:** draft
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** Datacollector에서 자동 추출된 위키 데이터의 초기 통합.
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
- **기존 유사 문서:** None
|
||||
- **처리 방식:** CREATE
|
||||
- **처리 이유:** 신규 지식 체계 도입
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
function validate(order: Order) { ... }
|
||||
function calculateTotal(order: Order) { ... }
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### Primitive Obsession → Value Object
|
||||
```ts
|
||||
// ❌
|
||||
function transfer(amount: number, currency: string) { ... }
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
// ✅
|
||||
class Money {
|
||||
constructor(public amount: bigint, public currency: string) {}
|
||||
add(other: Money) {
|
||||
if (this.currency !== other.currency) throw new Error();
|
||||
return new Money(this.amount + other.amount, this.currency);
|
||||
}
|
||||
}
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
function transfer(money: Money) { ... }
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### Switch → Polymorphism
|
||||
```ts
|
||||
// ❌
|
||||
function area(shape: Shape) {
|
||||
switch (shape.type) {
|
||||
case 'circle': return Math.PI * shape.r ** 2;
|
||||
case 'square': return shape.side ** 2;
|
||||
case 'rectangle': return shape.w * shape.h;
|
||||
}
|
||||
}
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
// ✅
|
||||
abstract class Shape { abstract area(): number; }
|
||||
class Circle extends Shape { constructor(public r: number) {} area() { return Math.PI * this.r ** 2; } }
|
||||
class Square extends Shape { constructor(public side: number) {} area() { return this.side ** 2; } }
|
||||
```
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
### Feature Envy → Move Method
|
||||
```ts
|
||||
// ❌
|
||||
class Order {
|
||||
total(customer: Customer) {
|
||||
// 매 모든 logic 의 customer 의 사용
|
||||
return customer.discount * customer.tax * ...;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Move to Customer
|
||||
class Customer {
|
||||
applyDiscount(amount: number) { return amount * this.discountRate; }
|
||||
}
|
||||
```
|
||||
|
||||
### Message Chain → Hide Delegate
|
||||
```ts
|
||||
// ❌ Chain
|
||||
order.getCustomer().getAddress().getCountry().getName();
|
||||
|
||||
// ✅ Hide
|
||||
class Order {
|
||||
customerCountry() {
|
||||
return this.customer.address.country.name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Detection (Semgrep)
|
||||
```yaml
|
||||
# 매 long parameter list detection
|
||||
rules:
|
||||
- id: long-parameter-list
|
||||
pattern-either:
|
||||
- pattern: function $F($A, $B, $C, $D, $E, ...) { ... }
|
||||
message: "Function has 5+ parameters — consider Parameter Object"
|
||||
severity: WARNING
|
||||
languages: [typescript, javascript]
|
||||
```
|
||||
|
||||
### SonarQube quality gate
|
||||
```properties
|
||||
# 매 cognitive complexity
|
||||
sonar.javascript.cognitive-complexity-threshold=15
|
||||
|
||||
# 매 duplicate threshold
|
||||
sonar.cpd.minimumLines=20
|
||||
sonar.duplicatedLines.maximum=3.0
|
||||
```
|
||||
|
||||
### AI review (CodeRabbit)
|
||||
```yaml
|
||||
# .coderabbit.yaml
|
||||
language: en
|
||||
reviews:
|
||||
profile: chill
|
||||
high_level_summary: true
|
||||
poem: false
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
|
||||
# 매 auto-detect: long methods, missing tests, complexity, etc.
|
||||
```
|
||||
|
||||
### Refactor metric (cyclomatic complexity)
|
||||
```bash
|
||||
# 매 radon (Python)
|
||||
radon cc src/ -a -nb
|
||||
|
||||
# 매 ESLint complexity rule
|
||||
echo '{ "rules": { "complexity": ["error", 10] } }' > .eslintrc.json
|
||||
```
|
||||
|
||||
### Bobby tables (refactor cadence)
|
||||
```python
|
||||
# 매 boy scout rule
|
||||
def visit(file):
|
||||
if needs_change(file):
|
||||
# 매 main change
|
||||
do_main_change()
|
||||
# 매 small refactor (touching area)
|
||||
if has_smell(file):
|
||||
small_refactor()
|
||||
```
|
||||
|
||||
## 🤔 결정 기준
|
||||
| Smell | Refactor |
|
||||
|---|---|
|
||||
| Long Method | Extract Method |
|
||||
| Large Class | Extract Class |
|
||||
| Primitive Obsession | Value Object |
|
||||
| Long Parameter | Parameter Object |
|
||||
| Duplicate | DRY (Extract) |
|
||||
| Switch | Polymorphism |
|
||||
| Feature Envy | Move Method |
|
||||
| Data Clump | Class |
|
||||
| Comments (bad) | Rename / Restructure |
|
||||
| Magic Number | Named Constant |
|
||||
|
||||
**기본값**: 매 fix-as-you-touch + 매 priority queue (changing area).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Refactoring]] · [[Code-Quality]] · [[Software-Engineering]]
|
||||
- 변형: [[Bloater]] · [[Coupler]] · [[Dispensable]] · [[Change-Preventer]]
|
||||
- 응용: [[Extract-Method]] · [[Replace-Conditional-with-Polymorphism]] · [[Move-Method]]
|
||||
- 비판: [[Anaemic-Domain-Model]] (Data Class)
|
||||
- Adjacent: [[Architecture-Anti-Patterns]] · [[Quality_Code_Review_Modern]] · [[Clean-Code-Principles]] · [[SOLID]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 code review. 매 refactor planning. 매 onboarding (smell 의 catalog 인지).
|
||||
**언제 X**: 매 prototype (premature). 매 throwaway script.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **모든 smell 의 fix 의 obsession**: 매 productivity ↓.
|
||||
- **No measure**: 매 better 의 prove 의 X.
|
||||
- **Smell 의 ignore**: 매 technical debt 의 accumulate.
|
||||
- **Refactor without test**: 매 regression.
|
||||
- **Big bang refactor**: 매 risky.
|
||||
- **Clean Code 의 dogma**: 매 sometimes wrong.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Fowler "Refactoring", Beck "Implementation Patterns", SonarQube rules).
|
||||
- 신뢰도 A.
|
||||
- Related: [[Architecture-Anti-Patterns]] · [[Anaemic-Domain-Model]] · [[Quality_Code_Review_Modern]] · [[Clean-Code-Principles]].
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 6 category + refactor + 매 TS / Semgrep / SonarQube code |
|
||||
|
||||
Reference in New Issue
Block a user