Claude Code Plugins

Community-maintained marketplace

Feedback

code-smell-detector

@ntaksh42/agents
0
0

Detect code smells including long methods, large classes, duplicated code, and deep nesting. Use when identifying code quality issues or planning refactoring.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name code-smell-detector
description Detect code smells including long methods, large classes, duplicated code, and deep nesting. Use when identifying code quality issues or planning refactoring.

Code Smell Detector Skill

コードの問題パターン(コードスメル)を検出するスキルです。

概要

保守性を低下させるコードパターンを検出し、リファクタリングを提案します。

検出するコードスメル

1. Long Method(長すぎるメソッド)

// ❌ Bad: 100行のメソッド
function processOrder(order) {
  // 検証ロジック 20行
  // 在庫チェック 15行
  // 価格計算 20行
  // 決済処理 25行
  // メール送信 15行
  // ログ記録 5行
}

// ✅ Good: 分割
function processOrder(order) {
  validateOrder(order);
  checkInventory(order);
  const total = calculateTotal(order);
  processPayment(order, total);
  sendConfirmationEmail(order);
  logOrder(order);
}

2. Duplicate Code(重複コード)

# ❌ Bad
def calculate_user_discount(user):
    if user.type == 'premium':
        return user.total * 0.9
    elif user.type == 'vip':
        return user.total * 0.8
    return user.total

def calculate_order_price(order):
    if order.user.type == 'premium':
        return order.total * 0.9
    elif order.user.type == 'vip':
        return order.total * 0.8
    return order.total

# ✅ Good
DISCOUNT_RATES = {
    'premium': 0.9,
    'vip': 0.8,
    'regular': 1.0
}

def apply_discount(total, user_type):
    rate = DISCOUNT_RATES.get(user_type, 1.0)
    return total * rate

3. Large Class(巨大クラス)

// ❌ Bad: 1000行のクラス
class UserManager {
    void createUser() {}
    void updateUser() {}
    void deleteUser() {}
    void sendEmail() {}
    void generateReport() {}
    void processPayment() {}
    void managePermissions() {}
    // ... 50個のメソッド
}

// ✅ Good: 責務を分離
class UserRepository {
    void create(User user) {}
    void update(User user) {}
    void delete(String id) {}
}

class EmailService {
    void send(Email email) {}
}

class PaymentService {
    void process(Payment payment) {}
}

4. Magic Numbers(マジックナンバー)

// ❌ Bad
if (user.age > 18 && user.score >= 75) {
  // ...
}

// ✅ Good
const ADULT_AGE = 18;
const PASSING_SCORE = 75;

if (user.age > ADULT_AGE && user.score >= PASSING_SCORE) {
  // ...
}

5. Deep Nesting(深いネスト)

# ❌ Bad
def process(data):
    if data:
        if data.valid:
            if data.user:
                if data.user.active:
                    if data.amount > 0:
                        # 処理
                        return True
    return False

# ✅ Good: Early return
def process(data):
    if not data or not data.valid:
        return False

    if not data.user or not data.user.active:
        return False

    if data.amount <= 0:
        return False

    # 処理
    return True

6. Dead Code(デッドコード)

// ❌ Bad
function calculatePrice(item: Item): number {
  const tax = 0.1; // 使われていない
  const oldPrice = item.price * 1.2; // 使われていない

  return item.price;
}

// ✅ Good
function calculatePrice(item: Item): number {
  return item.price;
}

7. Comment Smell(不適切なコメント)

// ❌ Bad
// このメソッドはユーザーを取得します
public User getUser(String id) {
    // IDでデータベースを検索
    return database.find(id);
}

// ✅ Good: コードで表現
public User findUserById(String id) {
    return userRepository.findById(id);
}

8. Feature Envy(機能への羨望)

# ❌ Bad: OrderクラスがUserの詳細を知りすぎ
class Order:
    def calculate_discount(self, user):
        if user.type == 'premium':
            return self.total * user.premium_rate
        elif user.type == 'vip':
            return self.total * user.vip_rate
        return self.total

# ✅ Good: Userに責務を移動
class User:
    def get_discount_rate(self):
        rates = {'premium': 0.9, 'vip': 0.8}
        return rates.get(self.type, 1.0)

class Order:
    def calculate_discount(self, user):
        return self.total * user.get_discount_rate()

9. Primitive Obsession(基本型への執着)

// ❌ Bad
function sendEmail(to: string, subject: string, body: string) {
  // ...
}

sendEmail('user@example.com', 'Hello', 'Message');

// ✅ Good
class Email {
  constructor(
    public to: string,
    public subject: string,
    public body: string
  ) {}

  validate(): boolean {
    return /\S+@\S+\.\S+/.test(this.to);
  }
}

function sendEmail(email: Email) {
  if (!email.validate()) {
    throw new Error('Invalid email');
  }
  // ...
}

10. Switch Statement Smell

// ❌ Bad
public double calculateArea(Shape shape) {
    switch (shape.getType()) {
        case CIRCLE:
            return Math.PI * shape.getRadius() * shape.getRadius();
        case RECTANGLE:
            return shape.getWidth() * shape.getHeight();
        case TRIANGLE:
            return 0.5 * shape.getBase() * shape.getHeight();
    }
    return 0;
}

// ✅ Good: ポリモーフィズム
interface Shape {
    double calculateArea();
}

class Circle implements Shape {
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    public double calculateArea() {
        return width * height;
    }
}

検出レポート例

## コードスメル検出レポート

### ファイル: user_service.py

#### [HIGH] Long Method
**場所**: Line 45-120 (76行)
**メソッド**: `process_user_registration`
**推奨**: 以下に分割
- `validate_user_data`
- `create_user_account`
- `send_welcome_email`
- `initialize_user_settings`

#### [MEDIUM] Duplicate Code
**場所**: Line 150-165, Line 200-215
**重複度**: 95%
**推奨**: 共通関数 `apply_user_discount` に抽出

#### [LOW] Magic Number
**場所**: Line 78
**コード**: `if age > 18`
**推奨**: `ADULT_AGE = 18` と定数化

### 統計
- Total Code Smells: 12
- High Priority: 3
- Medium Priority: 5
- Low Priority: 4

バージョン情報

  • スキルバージョン: 1.0.0