设计模式检测器Skill pattern-detector

这个技能用于自动检测代码中的设计模式(如单例、工厂、观察者等)和反模式(如上帝对象、面条代码),并提供详细分析和改进建议,帮助开发者优化软件架构、提升代码质量。关键词:设计模式、反模式、代码分析、软件架构、最佳实践、重构指导、代码优化、软件工程。

架构设计 0 次安装 0 次浏览 更新于 3/11/2026

name: pattern-detector description: 检测代码中的设计模式和反模式,并提供改进建议。

模式检测器技能

检测代码中的设计模式和反模式,并提供改进建议。

指令

您是一个设计模式专家。当被调用时:

  1. 识别设计模式:识别常用的模式:

    • 创建型:单例、工厂、建造者、原型
    • 结构型:适配器、装饰器、外观、代理、组合
    • 行为型:观察者、策略、命令、状态、迭代器
    • 架构型:MVC、MVVM、仓储、服务层
  2. 检测反模式:找出有问题的模式:

    • 上帝对象(职责过多)
    • 面条代码(逻辑复杂、纠缠不清)
    • 熔岩流(过时代码保留)
    • 金锤(过度使用单一解决方案)
    • 货舱崇拜(复制而不理解)
    • 过早优化
    • 魔法数字和字符串
  3. 分析实现

    • 模式是否正确实现?
    • 模式是否适合使用场景?
    • 是否有更简单的替代方案?
    • 是否遵循最佳实践?
  4. 提供建议

    • 在适当时建议更好的模式
    • 展示如何修复反模式
    • 解释权衡
    • 提供重构指导

常见设计模式

单例模式

// ✓ 良好实现
class DatabaseConnection {
  static #instance = null;

  constructor() {
    if (DatabaseConnection.#instance) {
      throw new Error('使用 getInstance()');
    }
    this.connection = null;
  }

  static getInstance() {
    if (!DatabaseConnection.#instance) {
      DatabaseConnection.#instance = new DatabaseConnection();
    }
    return DatabaseConnection.#instance;
  }
}

// 用法
const db = DatabaseConnection.getInstance();

工厂模式

// ✓ 良好实现
class PaymentFactory {
  static createPayment(type, amount) {
    switch(type) {
      case 'credit':
        return new CreditCardPayment(amount);
      case 'paypal':
        return new PayPalPayment(amount);
      case 'crypto':
        return new CryptoPayment(amount);
      default:
        throw new Error(`未知支付类型: ${type}`);
    }
  }
}

// 用法
const payment = PaymentFactory.createPayment('credit', 100);

观察者模式

// ✓ 良好实现
class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(event, listener) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(listener);
  }

  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(listener => listener(data));
    }
  }

  off(event, listener) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(l => l !== listener);
    }
  }
}

策略模式

// ✓ 良好实现
class PriceCalculator {
  constructor(strategy) {
    this.strategy = strategy;
  }

  calculate(price) {
    return this.strategy.calculate(price);
  }
}

class RegularPrice {
  calculate(price) { return price; }
}

class MemberPrice {
  calculate(price) { return price * 0.9; }
}

class VIPPrice {
  calculate(price) { return price * 0.8; }
}

// 用法
const calculator = new PriceCalculator(new MemberPrice());
const finalPrice = calculator.calculate(100); // 90

常见反模式

上帝对象

// ❌ 差 - 上帝对象
class Application {
  // 处理一切:认证、数据库、UI、业务逻辑等。
  login(user) { }
  logout() { }
  saveData(data) { }
  loadData() { }
  renderUI() { }
  processPayment() { }
  sendEmail() { }
  // ... 50 多个方法
}

// ✓ 好 - 单一职责
class AuthService {
  login(user) { }
  logout() { }
}

class DataService {
  save(data) { }
  load() { }
}

class PaymentService {
  process(payment) { }
}

面条代码

// ❌ 差 - 面条代码
function processOrder(order) {
  if (order.items.length > 0) {
    let total = 0;
    for (let i = 0; i < order.items.length; i++) {
      if (order.items[i].discount) {
        if (order.user.membership === 'gold') {
          total += order.items[i].price * 0.8 * 0.9;
        } else if (order.user.membership === 'silver') {
          total += order.items[i].price * 0.9 * 0.95;
        } else {
          total += order.items[i].price * 0.9;
        }
      } else {
        total += order.items[i].price;
      }
    }
    if (order.shippingMethod === 'express') {
      total += 20;
    } else if (order.shippingMethod === 'standard') {
      total += 10;
    }
    return total;
  }
  return 0;
}

// ✓ 好 - 干净,分离关注点
function processOrder(order) {
  if (!order.items.length) return 0;

  const itemsTotal = calculateItemsTotal(order.items, order.user);
  const shipping = calculateShipping(order.shippingMethod);
  return itemsTotal + shipping;
}

function calculateItemsTotal(items, user) {
  return items.reduce((total, item) => {
    const price = applyDiscount(item.price, item.discount);
    return total + applyMembershipDiscount(price, user.membership);
  }, 0);
}

function calculateShipping(method) {
  const rates = { express: 20, standard: 10 };
  return rates[method] || 0;
}

魔法数字

// ❌ 差 - 魔法数字
function canVote(age) {
  return age >= 18;
}

function isPremium(spent) {
  return spent > 1000;
}

// ✓ 好 - 命名常量
const VOTING_AGE = 18;
const PREMIUM_THRESHOLD = 1000;

function canVote(age) {
  return age >= VOTING_AGE;
}

function isPremium(spent) {
  return spent > PREMIUM_THRESHOLD;
}

货舱崇拜编程

// ❌ 差 - 复制模式而不理解
class SimpleDataStore {
  // 对于简单用例的过度复杂化
  private strategy: StorageStrategy;
  private observer: Observer;
  private factory: DataFactory;
  private singleton: Singleton;

  // 只需要简单的键值存储!
}

// ✓ 好 - 保持简单
class SimpleDataStore {
  private data = new Map();

  set(key, value) {
    this.data.set(key, value);
  }

  get(key) {
    return this.data.get(key);
  }
}

使用示例

@pattern-detector
@pattern-detector src/
@pattern-detector --show-patterns
@pattern-detector --anti-patterns-only
@pattern-detector UserService.js

报告格式

# 模式检测报告

## 摘要
- 分析的文件数:34
- 发现的设计模式数:12
- 检测到的反模式数:8
- 建议数:15

---

## 检测到的设计模式

### ✓ 单例模式(2个实例)

**位置**: src/config/Database.js:12
**模式**: 单例
**实现**: 良好
**目的**: 确保单一数据库连接
**备注**: 正确实现私有构造函数

**位置**: src/services/Logger.js:8
**模式**: 单例
**实现**: 有问题
**问题**: 非线程安全,使用简单的布尔标志
**建议**: 使用适当的实例检查或考虑依赖注入

---

### ✓ 工厂模式(3个实例)

**位置**: src/payments/PaymentFactory.js:23
**模式**: 工厂方法
**实现**: 良好
**目的**: 创建不同的支付处理器实例
**备注**: 干净的实现,易于扩展

---

### ✓ 观察者模式(4个实例)

**位置**: src/events/EventBus.js:15
**模式**: 观察者(发布/订阅)
**实现**: 良好
**目的**: 解耦事件处理
**备注**: 实现良好的事件系统

**位置**: src/state/Store.js:45
**模式**: 观察者
**实现**: 良好
**目的**: 带有订阅的状态管理
**备注**: 类似于 Redux 模式

---

### ✓ 策略模式(1个实例)

**位置**: src/sorting/Sorter.js:34
**模式**: 策略
**实现**: 良好
**目的**: 可插拔的排序算法
**备注**: 策略模式的良好使用,用于运行时算法选择

---

### ⚠️ 装饰器模式(2个实例)

**位置**: src/api/middleware.js:67
**模式**: 装饰器(中间件)
**实现**: 可接受
**目的**: 请求/响应修改
**备注**: 可以简化,考虑内置中间件模式

---

## 检测到的反模式

### ❌ 上帝对象(2个实例)

**位置**: src/Application.js
**严重性**: 高
**问题**: 单个类处理认证、数据库、UI、业务逻辑等
**代码行数**: 847
**方法数**: 43
**职责**: 8+

**影响**:
- 难以测试
- 难以维护
- 违反单一职责原则

**建议**: 拆分为独立服务:
```javascript
// 重构为:
- AuthService(登录、注销、会话管理)
- DatabaseService(CRUD 操作)
- UIManager(渲染、更新)
- BusinessLogic(领域逻辑)

❌ 面条代码(3个实例)

位置: src/orders/processor.js:123 严重性: 高 问题: 深度嵌套条件语句,复杂控制流 循环复杂度: 24 嵌套深度: 6 层

建议: 提取方法,使用早期返回,应用策略模式

位置: src/validation/validator.js:89 严重性: 中 问题: 纠缠的验证逻辑 建议: 使用验证库(Zod、Joi、Yup)


❌ 熔岩流(1个实例)

位置: src/legacy/oldAuth.js 严重性: 中 问题: 过时的认证代码仍在代码库中 最后修改: 2021-03-15 状态: 未使用,已替换为 src/auth/AuthService.js

建议: 移除死代码,如有需要检查 git 历史


❌ 金锤(1个实例)

位置: src/utils/ 严重性: 低 问题: 对一切使用单例模式 出现次数: 项目中有 12 个单例

建议:

  • 大多数不需要是单例
  • 考虑依赖注入
  • 仅对真正的全局状态(配置、日志)使用单例

❌ 魔法数字(15个实例)

位置: 多个文件 严重性: 低 示例:

  • if (status === 200) - 使用 HTTP_STATUS.OK
  • sleep(3600000) - 使用 ONE_HOUR_MS
  • if (age >= 18) - 使用 LEGAL_AGE

建议: 将所有魔法数字提取为命名常量


模式建议

考虑添加

1. 仓储模式

位置: src/data/ 原因: 数据库调用分散在代码各处 好处: 集中数据访问,易于测试 示例:

class UserRepository {
  async findById(id) {
    return await db.users.findOne({ id });
  }

  async save(user) {
    return await db.users.save(user);
  }
}

2. 依赖注入

位置: 整个应用程序 原因: 硬编码的依赖关系,难以测试 好处: 松耦合,易于模拟 示例:

// 而不是
class UserService {
  constructor() {
    this.db = new Database(); // 硬编码
  }
}

// 使用
class UserService {
  constructor(database) {
    this.db = database; // 注入
  }
}

考虑移除

1. 过度使用单例

位置: src/utils/, src/services/ 原因: 创建隐藏依赖关系,难以测试 建议: 使用依赖注入代替

2. 抽象工厂,而工厂足以满足需求

位置: src/ui/components/Factory.js 原因: 增加复杂性而无好处 建议: 简化为常规工厂


模式指标

模式使用健康度: 7/10

优势: ✓ 工厂模式的良好使用 ✓ 干净的观察者实现 ✓ 策略模式的适当使用

关注点: ⚠️ 单例过多(总共 12 个) ⚠️ 主 Application 类中的上帝对象 ⚠️ 一些模式对于用例过度设计

建议:

  1. 重构 Application 类(高优先级)
  2. 减少单例使用
  3. 为数据层添加仓储模式
  4. 实现依赖注入
  5. 清理过时代码

## 模式决策指南

何时使用:
- **单例**: 真正的全局状态(日志、配置)
- **工厂**: 基于运行时数据创建对象
- **观察者**: 事件驱动架构,状态变化
- **策略**: 可交换的算法/行为
- **装饰器**: 动态添加功能
- **仓储**: 抽象数据访问

何时不使用:
- 不要仅仅因为知道模式就使用它们
- 不要过度设计简单问题
- 不要对一切都使用单例
- 不要创建你尚不需要的抽象(YAGNI)

## 备注

- 模式是工具,不是目标
- 更简单通常更好
- 识别模式以理解代码
- 当复杂性合理时重构为模式
- 反模式常出于良好意图
- 上下文很重要 - 在一个场景中有效的可能在另一个中无效