skills/code-smell/SKILL.md
코드 스멜 감지 및 개선 가이드를 실행합니다.
npx skillsauth add excatt/superclaude-plusplus code-smellInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
코드 스멜 감지 및 개선 가이드를 실행합니다.
코드 스멜 = 더 깊은 문제의 표면적 징후
- 버그는 아니지만 문제를 암시
- 리팩토링이 필요하다는 신호
- 기술 부채의 원인
// 스멜: 메서드가 너무 김 (>20줄)
function processOrder(order) {
// 100줄의 코드...
}
// 해결: Extract Function
function processOrder(order) {
validateOrder(order);
calculatePricing(order);
applyDiscounts(order);
processPayment(order);
sendConfirmation(order);
}
// 스멜: 클래스가 너무 많은 책임
class User {
// 사용자 데이터, 인증, 이메일, 보고서, 결제...
// 500줄 이상
}
// 해결: Extract Class
class User { /* 사용자 데이터만 */ }
class AuthService { /* 인증 */ }
class EmailService { /* 이메일 */ }
// 스멜: 기본 타입 남용
const price = 1000; // 통화는? 단위는?
const phone = "010-1234-5678"; // 검증은?
// 해결: Replace Primitive with Object
class Money {
constructor(amount, currency) {}
add(other) {}
}
class PhoneNumber {
constructor(number) { this.validate(number); }
}
// 스멜: 매개변수가 너무 많음
function createUser(name, email, age, address, city, country, phone, role) {}
// 해결: Introduce Parameter Object
function createUser(userParams) {}
// 또는 Builder 패턴
// 스멜: 항상 함께 다니는 데이터 그룹
function renderMap(startX, startY, endX, endY) {}
function calculateDistance(x1, y1, x2, y2) {}
// 해결: Extract Class
class Point { constructor(x, y) {} }
function renderMap(start: Point, end: Point) {}
// 스멜: switch/if-else 반복
function getArea(shape) {
switch (shape.type) {
case 'circle': return Math.PI * shape.r ** 2;
case 'rectangle': return shape.w * shape.h;
// 새 타입 추가 시 모든 switch 수정...
}
}
// 해결: Replace with Polymorphism
interface Shape { getArea(): number; }
class Circle implements Shape { getArea() { return Math.PI * this.r ** 2; } }
class Rectangle implements Shape { getArea() { return this.w * this.h; } }
// 스멜: 상속받았지만 사용 안 함
class Bird {
fly() {}
eat() {}
}
class Penguin extends Bird {
fly() { throw new Error("Can't fly"); } // 거부!
}
// 해결: Replace Inheritance with Delegation
interface Flyable { fly(): void; }
class Penguin implements Eatable { /* fly 없음 */ }
// 스멜: 특정 상황에서만 사용되는 필드
class Order {
items = [];
tempDiscount = null; // 특정 계산에서만 사용
tempTax = null;
}
// 해결: Extract Class 또는 Introduce Null Object
class OrderCalculation {
constructor(order) {}
calculateDiscount() {}
calculateTax() {}
}
// 스멜: 한 클래스가 여러 이유로 변경됨
class Report {
// DB 변경 시 수정
// 출력 형식 변경 시 수정
// 계산 로직 변경 시 수정
}
// 해결: Extract Class (각 변경 이유별로)
class ReportData { /* DB 관련 */ }
class ReportFormatter { /* 출력 형식 */ }
class ReportCalculator { /* 계산 로직 */ }
// 스멜: 하나의 변경이 여러 클래스에 영향
// 사용자 이름 형식 변경 → 10개 파일 수정
// 해결: Move Method, Move Field
// 관련 코드를 한 곳으로 모음
// 스멜: 한 클래스 계층 추가 시 다른 계층도 추가 필요
// Shape 추가 시 ShapeRenderer도 추가
// 해결: Move Method
// 일반적으로 한 계층을 다른 계층으로 통합
// 스멜: 코드 설명을 위한 과도한 주석
// 이 함수는 사용자가 성인인지 확인합니다
// 18세 이상이면 true를 반환합니다
function check(u) {
return u.a >= 18;
}
// 해결: Rename, Extract Function
function isAdult(user) {
return user.age >= 18;
}
// 스멜: 동일하거나 유사한 코드 반복
// 해결: Extract Function, Pull Up Method, Form Template Method
// 스멜: 사용되지 않는 코드
function oldMethod() { /* 아무데서도 호출 안 됨 */ }
if (false) { /* 절대 실행 안 됨 */ }
// 해결: Remove Dead Code
// 스멜: "나중에 필요할 것 같아서" 만든 코드
class AbstractFactory { } // 구현체 1개뿐
function process(data, options = {}, callback, errorHandler, logger) {
// options, callback 등 사용 안 됨
}
// 해결: Remove (YAGNI 적용)
// 스멜: 다른 클래스 데이터를 과도하게 사용
class Order {
getDiscount() {
return this.customer.loyaltyPoints > 100
? this.customer.membershipLevel === 'gold'
? this.total * 0.2
: this.total * 0.1
: 0;
}
}
// 해결: Move Method to Customer
class Customer {
getDiscount(orderTotal) { /* ... */ }
}
// 스멜: 클래스 간 과도한 결합
class A {
constructor() {
this.b = new B();
this.b._privateField = 10; // private 접근
}
}
// 해결: Move Method, Extract Class, 인터페이스 도입
// 스멜: 긴 메서드 체인 (디미터 법칙 위반)
const zip = person.getDepartment().getAddress().getZipCode();
// 해결: Hide Delegate
class Person {
getDepartmentZipCode() {
return this.department.getZipCode();
}
}
| 카테고리 | 스멜 | 징후 | |---------|------|------| | Bloaters | Long Method | >20줄 | | Bloaters | Large Class | >200줄, 많은 필드 | | Bloaters | Long Parameter List | >3개 | | OO Abusers | Switch | 반복되는 switch/if-else | | Change Preventers | Shotgun Surgery | 작은 변경 → 많은 파일 수정 | | Dispensables | Dead Code | 호출되지 않는 코드 | | Couplers | Feature Envy | 다른 클래스 데이터 과다 사용 |
## Code Smell Analysis
### Summary
- Critical: N개
- Warning: N개
- Info: N개
### Detected Smells
#### [Critical] Long Method
- 위치: `processOrder()` (85줄)
- 문제: 메서드가 너무 길어 이해/유지보수 어려움
- 해결: Extract Function으로 분리
```javascript
// Before (85 lines)
function processOrder() { ... }
// After (분리된 함수들)
function validateOrder() { ... }
function calculateTotal() { ... }
---
요청에 맞는 코드 스멜 분석을 수행하세요.
testing
사용자 계획을 기존 도메인 모델에 대해 stress-test하는 인터뷰 세션. 용어를 날카롭게 다듬고, 결정이 굳어질 때마다 CONTEXT.md(도메인 어휘 사전)와 ADR을 인라인으로 갱신한다. 새 기능 요구사항 탐색은 `/brainstorm`을, 기존 도메인 모델·용어와의 정합성 점검은 이 스킬을 사용한다.
development
# Excel (XLSX) Spreadsheet Skill Claude Code supports comprehensive spreadsheet operations through the **xlsx** skill, enabling creation, editing, and analysis of Excel files (.xlsx, .xlsm, .csv, .tsv). ## Trigger - When user needs Excel spreadsheet creation or editing - Financial modeling or data analysis required - Spreadsheet formulas and calculations needed - Data import from CSV/TSV files ## Core Capabilities **Primary functions include:** - Creating new spreadsheets with formulas and f
tools
Generate structured implementation workflows from PRDs and feature requirements
development
실시간 통신 설계 가이드를 실행합니다.