2025-08-31 13:10
Tags: 설계 원칙
코드 스멜
- 버그는 아니지만 코드의 구조적인 문제
 - 꾸준히 식별해 리팩토링하고 디자인 패턴을 지켜나가며 줄이고 개선하는 것은 매우 좋은 습관
 - 의식적으로 배우는 것도 있고 짬에서 나오는 바이브도 있는 듯
 
| 코드 스멜 (Code Smell) | 설명 | 대표적인 리팩토링 기법 | 
|---|---|---|
| 거대한 놈들 (Bloaters) | ||
| 긴 메서드 (Long Method) | 하나의 메서드가 너무 많은 일을 하고, 코드가 수십, 수백 줄에 달하는 경우. | 메서드 추출 (Extract Method): 코드의 일부를 새로운 메서드로 분리. | 
| 거대 클래스 (Large Class) | 하나의 클래스가 너무 많은 책임과 데이터를 가지고 있는 경우. | 클래스 추출 (Extract Class): 클래스의 일부를 새 클래스로 분리. | 
| 원시 타입 집착 (Primitive Obsession) | 전화번호, 금액, 단위 등 의미 있는 데이터를 단순 문자열이나 숫자로만 다루는 경우. | 값을 객체로 변환 (Replace Primitive with Object): 원시 타입을 의미 있는 객체로 포장. | 
| 긴 매개변수 목록 (Long Parameter List) | 메서드에 전달하는 매개변수가 3~4개를 넘어가는 경우. | 매개변수 객체화 (Introduce Parameter Object): 매개변수들을 하나의 객체로 묶음. | 
| 데이터 뭉치 (Data Clumps) | 여러 곳에서 항상 함께 나타나는 데이터 그룹 (예: 시작일, 종료일). | 클래스 추출 (Extract Class): 데이터 뭉치를 자신만의 클래스로 만듦. | 
| 객체 지향 원칙 위반 (Object-Orientation Abusers) | ||
| Switch 문 (Switch Statements) | 유사한 형태의 switch 문이 여러 곳에 반복적으로 나타나는 경우. | 다형성으로 전환 (Replace Conditional with Polymorphism): 조건문을 하위 클래스나 전략 패턴으로 대체. | 
| 임시 필드 (Temporary Field) | 클래스의 인스턴스 변수(필드)가 특정 상황에서만 사용되는 경우. | 클래스 추출 (Extract Class): 임시 필드와 관련된 코드를 새 클래스로 옮김. | 
| 상속 거부 (Refused Bequest) | 부모 클래스의 메서드나 데이터 중 일부만 필요하고 나머지는 사용하지 않는 경우. | 상속을 위임으로 전환 (Replace Inheritance with Delegation) | 
| 변경을 막는 놈들 (Change Preventers) | ||
| 발산적 변경 (Divergent Change) | 하나의 클래스가 서로 다른 이유로 자주 변경되는 경우. | 클래스 추출 (Extract Class): 변경의 이유에 따라 클래스를 분리. | 
| 산탄총 수술 (Shotgun Surgery) | 작은 변경 하나를 위해 여러 클래스를 조금씩 수정해야 하는 경우. | 메서드/필드 이동 (Move Method/Field): 관련된 코드들을 한 클래스로 모음. | 
| 불필요한 놈들 (Dispensables) | ||
| 주석 (Comments) | 코드가 복잡해서 어쩔 수 없이 다는 주석. 좋은 코드는 주석 없이도 이해할 수 있어야 함. | 메서드 추출 (Extract Method), 변수명 변경 (Rename Variable): 코드를 명확하게 만들어 주석을 불필요하게 만듦. | 
| 중복 코드 (Duplicate Code) | 똑같거나 거의 비슷한 코드가 여러 곳에 존재하는 경우. | 메서드 추출 (Extract Method), 상위 클래스로 메서드 이동 (Pull Up Method) | 
| 죽은 코드 (Dead Code) | 더 이상 사용되지 않지만 삭제되지 않고 남아있는 코드. | 죽은 코드 제거 (Remove Dead Code) | 
| 쓸데없이 엮인 놈들 (Couplers) | ||
| 기능 편애 (Feature Envy) | 한 메서드가 자신이 속한 클래스의 데이터보다 다른 클래스의 데이터를 더 많이 사용하는 경우. | 메서드 이동 (Move Method): 해당 메서드를 데이터가 있는 클래스로 이동. | 
| 부적절한 친밀함 (Inappropriate Intimacy) | 두 클래스가 서로의 내부 구현에 너무 깊이 의존하는 경우. | 메서드/필드 이동 (Move Method/Field), 클래스 추출 (Extract Class) | 
| 메시지 체인 (Message Chains) | a.getB().getC().doSomething()처럼 객체를 통해 계속 다른 객체를 요청하는 코드. | 체인 숨기기 (Hide Delegate): 중간 객체에 위임 메서드를 만들어 체인을 숨김. |