skills/ntaksh42/agents/code-smell-detector

code-smell-detector

SKILL.md

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
Weekly Installs
6
Repository
ntaksh42/agents
GitHub Stars
1
First Seen
Jan 29, 2026
Installed on
claude-code6
opencode4
gemini-cli4
github-copilot4
codex4
kimi-cli4