design-patterns-implementation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDesign Patterns Implementation
设计模式实现
Overview
概述
Apply proven design patterns to create maintainable, extensible, and testable code architectures.
应用经过验证的设计模式来创建可维护、可扩展且可测试的代码架构。
When to Use
适用场景
- Solving common architectural problems
- Making code more maintainable and testable
- Implementing extensible plugin systems
- Decoupling components
- Following SOLID principles
- Code reviews identifying architectural issues
- 解决常见架构问题
- 提升代码的可维护性与可测试性
- 实现可扩展的插件系统
- 解耦组件
- 遵循SOLID原则
- 代码评审中发现架构问题时
Common Design Patterns
常见设计模式
1. Singleton Pattern
1. Singleton模式
Ensure a class has only one instance with global access.
typescript
class DatabaseConnection {
private static instance: DatabaseConnection;
private connection: any;
private constructor() {
this.connection = this.createConnection();
}
public static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
private createConnection() {
return { /* connection logic */ };
}
}
// Usage
const db1 = DatabaseConnection.getInstance();
const db2 = DatabaseConnection.getInstance();
// db1 === db2 (same instance)确保一个类只有一个实例,并提供全局访问点。
typescript
class DatabaseConnection {
private static instance: DatabaseConnection;
private connection: any;
private constructor() {
this.connection = this.createConnection();
}
public static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
private createConnection() {
return { /* connection logic */ };
}
}
// Usage
const db1 = DatabaseConnection.getInstance();
const db2 = DatabaseConnection.getInstance();
// db1 === db2 (same instance)2. Factory Pattern
2. Factory模式
Create objects without specifying exact classes.
python
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def process_payment(self, amount: float) -> bool:
pass
class StripeProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
# Stripe-specific logic
return True
class PayPalProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
# PayPal-specific logic
return True
class PaymentProcessorFactory:
@staticmethod
def create_processor(processor_type: str) -> PaymentProcessor:
if processor_type == 'stripe':
return StripeProcessor()
elif processor_type == 'paypal':
return PayPalProcessor()
else:
raise ValueError(f'Unknown processor: {processor_type}')无需指定具体类即可创建对象。
python
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def process_payment(self, amount: float) -> bool:
pass
class StripeProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
# Stripe-specific logic
return True
class PayPalProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
# PayPal-specific logic
return True
class PaymentProcessorFactory:
@staticmethod
def create_processor(processor_type: str) -> PaymentProcessor:
if processor_type == 'stripe':
return StripeProcessor()
elif processor_type == 'paypal':
return PayPalProcessor()
else:
raise ValueError(f'Unknown processor: {processor_type}')
// Usage
processor = PaymentProcessorFactory.create_processor('stripe')
processor.process_payment(100.00)Usage
3. Observer模式
processor = PaymentProcessorFactory.create_processor('stripe')
processor.process_payment(100.00)
undefined定义一对多的依赖关系,实现事件通知。
javascript
class Subject {
constructor() {
this.observers = [];
}
attach(observer) {
this.observers.push(observer);
}
detach(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
update(data) {
console.log('Received update:', data);
}
}
// Usage
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.attach(observer1);
subject.attach(observer2);
subject.notify({ event: 'data_changed' });3. Observer Pattern
4. Strategy模式
Define one-to-many dependency for event notification.
javascript
class Subject {
constructor() {
this.observers = [];
}
attach(observer) {
this.observers.push(observer);
}
detach(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
update(data) {
console.log('Received update:', data);
}
}
// Usage
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.attach(observer1);
subject.attach(observer2);
subject.notify({ event: 'data_changed' });定义一系列算法,并使它们可以互相替换。
java
interface CompressionStrategy {
byte[] compress(byte[] data);
}
class ZipCompression implements CompressionStrategy {
public byte[] compress(byte[] data) {
// ZIP compression logic
return data;
}
}
class GzipCompression implements CompressionStrategy {
public byte[] compress(byte[] data) {
// GZIP compression logic
return data;
}
}
class FileCompressor {
private CompressionStrategy strategy;
public FileCompressor(CompressionStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(CompressionStrategy strategy) {
this.strategy = strategy;
}
public byte[] compressFile(byte[] data) {
return strategy.compress(data);
}
}
// Usage
FileCompressor compressor = new FileCompressor(new ZipCompression());
compressor.compressFile(fileData);
// Change strategy at runtime
compressor.setStrategy(new GzipCompression());
compressor.compressFile(fileData);4. Strategy Pattern
5. Decorator模式
Define family of algorithms and make them interchangeable.
java
interface CompressionStrategy {
byte[] compress(byte[] data);
}
class ZipCompression implements CompressionStrategy {
public byte[] compress(byte[] data) {
// ZIP compression logic
return data;
}
}
class GzipCompression implements CompressionStrategy {
public byte[] compress(byte[] data) {
// GZIP compression logic
return data;
}
}
class FileCompressor {
private CompressionStrategy strategy;
public FileCompressor(CompressionStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(CompressionStrategy strategy) {
this.strategy = strategy;
}
public byte[] compressFile(byte[] data) {
return strategy.compress(data);
}
}
// Usage
FileCompressor compressor = new FileCompressor(new ZipCompression());
compressor.compressFile(fileData);
// Change strategy at runtime
compressor.setStrategy(new GzipCompression());
compressor.compressFile(fileData);动态地为对象添加职责。
typescript
interface Coffee {
cost(): number;
description(): string;
}
class SimpleCoffee implements Coffee {
cost(): number {
return 5;
}
description(): string {
return 'Simple coffee';
}
}
class MilkDecorator implements Coffee {
constructor(private coffee: Coffee) {}
cost(): number {
return this.coffee.cost() + 2;
}
description(): string {
return this.coffee.description() + ', milk';
}
}
class SugarDecorator implements Coffee {
constructor(private coffee: Coffee) {}
cost(): number {
return this.coffee.cost() + 1;
}
description(): string {
return this.coffee.description() + ', sugar';
}
}
// Usage
let coffee: Coffee = new SimpleCoffee();
console.log(coffee.cost()); // 5
coffee = new MilkDecorator(coffee);
console.log(coffee.cost()); // 7
coffee = new SugarDecorator(coffee);
console.log(coffee.cost()); // 8
console.log(coffee.description()); // "Simple coffee, milk, sugar"5. Decorator Pattern
6. Repository模式
Add responsibilities to objects dynamically.
typescript
interface Coffee {
cost(): number;
description(): string;
}
class SimpleCoffee implements Coffee {
cost(): number {
return 5;
}
description(): string {
return 'Simple coffee';
}
}
class MilkDecorator implements Coffee {
constructor(private coffee: Coffee) {}
cost(): number {
return this.coffee.cost() + 2;
}
description(): string {
return this.coffee.description() + ', milk';
}
}
class SugarDecorator implements Coffee {
constructor(private coffee: Coffee) {}
cost(): number {
return this.coffee.cost() + 1;
}
description(): string {
return this.coffee.description() + ', sugar';
}
}
// Usage
let coffee: Coffee = new SimpleCoffee();
console.log(coffee.cost()); // 5
coffee = new MilkDecorator(coffee);
console.log(coffee.cost()); // 7
coffee = new SugarDecorator(coffee);
console.log(coffee.cost()); // 8
console.log(coffee.description()); // "Simple coffee, milk, sugar"抽象数据访问逻辑。
python
from abc import ABC, abstractmethod
from typing import List, Optional
class UserRepository(ABC):
@abstractmethod
def find_by_id(self, user_id: int) -> Optional[User]:
pass
@abstractmethod
def find_all(self) -> List[User]:
pass
@abstractmethod
def save(self, user: User) -> User:
pass
@abstractmethod
def delete(self, user_id: int) -> bool:
pass
class DatabaseUserRepository(UserRepository):
def __init__(self, db_connection):
self.db = db_connection
def find_by_id(self, user_id: int) -> Optional[User]:
result = self.db.query('SELECT * FROM users WHERE id = ?', user_id)
return User.from_dict(result) if result else None
def find_all(self) -> List[User]:
results = self.db.query('SELECT * FROM users')
return [User.from_dict(r) for r in results]
def save(self, user: User) -> User:
self.db.execute('INSERT INTO users (...) VALUES (...)', user.to_dict())
return user
def delete(self, user_id: int) -> bool:
return self.db.execute('DELETE FROM users WHERE id = ?', user_id)6. Repository Pattern
7. Dependency Injection(依赖注入)
Abstract data access logic.
python
from abc import ABC, abstractmethod
from typing import List, Optional
class UserRepository(ABC):
@abstractmethod
def find_by_id(self, user_id: int) -> Optional[User]:
pass
@abstractmethod
def find_all(self) -> List[User]:
pass
@abstractmethod
def save(self, user: User) -> User:
pass
@abstractmethod
def delete(self, user_id: int) -> bool:
pass
class DatabaseUserRepository(UserRepository):
def __init__(self, db_connection):
self.db = db_connection
def find_by_id(self, user_id: int) -> Optional[User]:
result = self.db.query('SELECT * FROM users WHERE id = ?', user_id)
return User.from_dict(result) if result else None
def find_all(self) -> List[User]:
results = self.db.query('SELECT * FROM users')
return [User.from_dict(r) for r in results]
def save(self, user: User) -> User:
self.db.execute('INSERT INTO users (...) VALUES (...)', user.to_dict())
return user
def delete(self, user_id: int) -> bool:
return self.db.execute('DELETE FROM users WHERE id = ?', user_id)通过注入依赖项来实现控制反转。
typescript
// Bad: Hard-coded dependencies
class OrderService {
private db = new MySQLDatabase(); // Tightly coupled
private email = new GmailService(); // Tightly coupled
createOrder(order: Order) {
this.db.save(order);
this.email.send(order.customer_email, 'Order created');
}
}
// Good: Dependency injection
interface Database {
save(entity: any): void;
}
interface EmailService {
send(to: string, subject: string): void;
}
class OrderService {
constructor(
private db: Database,
private email: EmailService
) {}
createOrder(order: Order) {
this.db.save(order);
this.email.send(order.customer_email, 'Order created');
}
}
// Usage - easy to test with mocks
const service = new OrderService(
new MySQLDatabase(),
new GmailService()
);
// Test with mocks
const testService = new OrderService(
new MockDatabase(),
new MockEmailService()
);7. Dependency Injection
最佳实践
—
✅ 建议
Invert control by injecting dependencies.
typescript
// Bad: Hard-coded dependencies
class OrderService {
private db = new MySQLDatabase(); // Tightly coupled
private email = new GmailService(); // Tightly coupled
createOrder(order: Order) {
this.db.save(order);
this.email.send(order.customer_email, 'Order created');
}
}
// Good: Dependency injection
interface Database {
save(entity: any): void;
}
interface EmailService {
send(to: string, subject: string): void;
}
class OrderService {
constructor(
private db: Database,
private email: EmailService
) {}
createOrder(order: Order) {
this.db.save(order);
this.email.send(order.customer_email, 'Order created');
}
}
// Usage - easy to test with mocks
const service = new OrderService(
new MySQLDatabase(),
new GmailService()
);
// Test with mocks
const testService = new OrderService(
new MockDatabase(),
new MockEmailService()
);- 选择能解决实际问题的模式
- 保持模式简单易懂
- 记录选择模式的原因
- 考虑可测试性
- 遵循SOLID原则
- 使用依赖注入
- 优先使用组合而非继承
Best Practices
❌ 避免
✅ DO
—
- Choose patterns that solve actual problems
- Keep patterns simple and understandable
- Document why patterns were chosen
- Consider testability
- Follow SOLID principles
- Use dependency injection
- Prefer composition over inheritance
- 在未理解模式的情况下应用
- 过度设计简单解决方案
- 强行套用不适合的模式
- 创建不必要的抽象层
- 忽略团队对模式的熟悉程度
❌ DON'T
各模式适用场景
- Apply patterns without understanding them
- Over-engineer simple solutions
- Force patterns where they don't fit
- Create unnecessary abstraction layers
- Ignore team familiarity with patterns
| 模式 | 使用场景 |
|---|---|
| Singleton | 数据库连接、配置管理器 |
| Factory | 根据运行时条件创建对象 |
| Observer | 事件系统、发布/订阅、响应式编程 |
| Strategy | 可在运行时切换的算法 |
| Decorator | 无需继承即可动态添加功能 |
| Repository | 抽象数据访问与业务逻辑 |
| Adapter | 使不兼容的接口协同工作 |
| Facade | 简化复杂子系统 |
| Command | 撤销/重做、任务队列、宏录制 |
When to Use Each Pattern
参考资源
| Pattern | Use Case |
|---|---|
| Singleton | Database connections, configuration managers |
| Factory | Creating objects based on runtime conditions |
| Observer | Event systems, pub/sub, reactive programming |
| Strategy | Algorithms that can be swapped at runtime |
| Decorator | Adding features dynamically without inheritance |
| Repository | Abstracting data access from business logic |
| Adapter | Making incompatible interfaces work together |
| Facade | Simplifying complex subsystems |
| Command | Undo/redo, task queuing, macro recording |
- 《Design Patterns》(Gang of Four 著)
- 《Head First Design Patterns》(Freeman & Freeman 著)
- refactoring.guru/design-patterns
Resources
—
- "Design Patterns" by Gang of Four
- "Head First Design Patterns" by Freeman & Freeman
- refactoring.guru/design-patterns
—