AgentSkillsCN

design-patterns

在 TypeScript 与 Node.js 中实现常见软件设计模式的参考指南。当需要架构建议,或对复杂逻辑进行重构时,可使用此技能。

SKILL.md
--- frontmatter
name: design-patterns
description: Reference for implementing common software design patterns in TypeScript and Node.js. Use when architectural advice is needed or when refactoring complex logic.

Design Patterns Skill

When to use

  • When the user asks to "structure the code better", "decouple logic", or specifically asks about a pattern.
  • When creating complex systems that need maintainability and scalability.

Common Patterns

1. Dependency Injection (DI)

  • Use Case: Decoupling components/services from their dependencies.
  • Implementation:
    • pass dependencies via constructor or factory function.
    • In Fastify, often achieved via fastify.decorate or passing instances during plugin registration.
    typescript
    class UserService {
      constructor(private db: Database) {}
    }
    

2. Singleton Pattern

  • Use Case: Ensuring a class has only one instance (e.g., Database Connection, Logger).
  • Implementation:
    • Export a shared instance from a module.
    • Node.js modules are cached, so export const db = new Database() acts as a singleton.

3. Factory Pattern

  • Use Case: Creating objects without specifying the exact class, or handling complex creation logic.
  • Implementation:
    typescript
    class NotificationFactory {
      static create(type: 'email' | 'sms') {
        if (type === 'email') return new EmailService();
        if (type === 'sms') return new SmsService();
      }
    }
    

4. Adapter Pattern

  • Use Case: Making incompatible interfaces work together (e.g., switching 3rd party libraries).
  • Implementation: Wrap the 3rd party lib in your own class implementing your interface.

5. Strategy Pattern

  • Use Case: Selecting an algorithm or business logic at runtime (e.g., different Payment Gateways).
  • Implementation: define a common interface (e.g., PaymentProvider) and swap implementations (StripeProvider, PayPalProvider) based on config or request.

6. Repository Pattern

  • Use Case: Abstraction layer between business logic and data access (DB).
  • Implementation:
    • UserRepository.findById(id)
    • Allows swapping ORMs or DBs without changing business rules.

7. Observer / Pub-Sub

  • Use Case: Event-driven architecture.
  • Implementation: EventEmitter in Node.js. useful for decoupling actions (e.g., "UserRegistered" -> "SendEmail", "CreateProfile").

Principles (SOLID)

  • S: Single Responsibility.
  • O: Open/Closed (open for extension, closed for modification).
  • L: Liskov Substitution.
  • I: Interface Segregation.
  • D: Dependency Inversion.