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): 중간 객체에 위임 메서드를 만들어 체인을 숨김. |