スキル一覧に戻る
ntaksh42

code-smell-detector

by ntaksh42

0🍴 1📅 2026年1月17日
GitHubで見るManusで実行

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

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です