
在现代 JavaScript 中哪些设计模式真正重要?
原始的 GoF《设计模式》一书(1994 年)用 C++ 描述了 23 种模式。其中许多模式解决的问题在 JavaScript 中处理方式不同——动态类型、一等函数和基于原型的对象显著改变了计算方式。
本指南聚焦于那些在 2026 年能真正改善实际代码库的模式:你会在流行框架、技术面试以及你实际维护的代码库中遇到的模式。

创建型模式
单例模式(Singleton)
确保一个类只有一个实例:
class DatabaseConnection {
private static instance: DatabaseConnection | null = null;
private pool: Pool;
private constructor() {
this.pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
});
}
// 获取实例的唯一方式
static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
async query(sql: string, params?: unknown[]) {
return this.pool.query(sql, params);
}
}
// 使用——总是获取同一个实例
const db1 = DatabaseConnection.getInstance();
const db2 = DatabaseConnection.getInstance();
console.log(db1 === db2); // true
// 现代替代方案:模块级单例(更简单)
// db.ts
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export default pool; // ES 模块默认就是单例!
工厂方法模式(Factory Method)
无需指定具体类即可创建对象:
interface Notifier {
send(to: string, message: string): Promise<void>;
}
class EmailNotifier implements Notifier {
async send(to: string, message: string) {
await sendEmail({ to, subject: 'Notification', body: message });
}
}
class SMSNotifier implements Notifier {
async send(to: string, message: string) {
await sendSMS({ phone: to, text: message });
}
}
class SlackNotifier implements Notifier {
async send(to: string, message: string) {
await postToSlack({ channel: to, text: message });
}
}
// 工厂
class NotifierFactory {
static create(type: 'email' | 'sms' | 'slack'): Notifier {
const map = {
email: EmailNotifier,
sms: SMSNotifier,
slack: SlackNotifier,
};
const NotifierClass = map[type];
if (!NotifierClass) throw new Error(`Unknown notifier type: ${type}`);
return new NotifierClass();
}
}
// 使用——客户端不知道创建了哪个类
const notifier = NotifierFactory.create(process.env.NOTIFIER_TYPE as 'email');
await notifier.send('alice@example.com', 'Your order is ready!');

建造者模式(Builder)
逐步构建复杂对象:
class QueryBuilder {
private table = '';
private conditions: string[] = [];
private columns = '*';
private limitVal?: number;
private orderByCol?: string;
private orderByDir = 'ASC';
private params: unknown[] = [];
from(table: string) {
this.table = table;
return this; // 方法链
}
select(...columns: string[]) {
this.columns = columns.join(', ');
return this;
}
where(condition: string, ...params: unknown[]) {
this.params.push(...params);
this.conditions.push(condition.replace('?', `${this.params.length}`));
return this;
}
limit(n: number) {
this.limitVal = n;
return this;
}
orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC') {
this.orderByCol = column;
this.orderByDir = direction;
return this;
}
build(): { sql: string; params: unknown[] } {
let sql = `SELECT ${this.columns} FROM ${this.table}`;
if (this.conditions.length > 0) {
sql += ` WHERE ${this.conditions.join(' AND ')}`;
}
if (this.orderByCol) {
sql += ` ORDER BY ${this.orderByCol} ${this.orderByDir}`;
}
if (this.limitVal !== undefined) {
sql += ` LIMIT ${this.limitVal}`;
}
return { sql, params: this.params };
}
}
// 清晰、可读的查询构建
const { sql, params } = new QueryBuilder()
.from('users')
.select('id', 'name', 'email')
.where('country = ?', 'US')
.where('created_at > ?', new Date('2026-01-01'))
.orderBy('name')
.limit(20)
.build();
结构型模式
装饰器模式(Decorator)
在不修改对象的情况下为其添加行为:
interface UserService {
findById(id: string): Promise<User | null>;
create(data: CreateUserDto): Promise<User>;
}
// 基础实现
class UserServiceImpl implements UserService {
async findById(id: string) {
return db.query('SELECT * FROM users WHERE id = $1', [id]);
}
async create(data: CreateUserDto) {
return db.query('INSERT INTO users ...', [data.name, data.email]);
}
}
// 缓存装饰器(包装服务)
class CachedUserService implements UserService {
constructor(
private service: UserService,
private cache: Redis
) {}
async findById(id: string) {
const cached = await this.cache.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await this.service.findById(id);
if (user) await this.cache.setEx(`user:${id}`, 3600, JSON.stringify(user));
return user;
}
async create(data: CreateUserDto) {
const user = await this.service.create(data);
await this.cache.setEx(`user:${user.id}`, 3600, JSON.stringify(user));
return user;
}
}
// 日志装饰器
class LoggingUserService implements UserService {
constructor(private service: UserService, private logger: Logger) {}
async findById(id: string) {
const start = Date.now();
const user = await this.service.findById(id);
this.logger.info({ id, duration: Date.now() - start }, 'findById');
return user;
}
// ... create 方法类似
}
// 组合:Logging(Caching(Base))
const userService: UserService =
new LoggingUserService(
new CachedUserService(
new UserServiceImpl(),
redis
),
logger
);

行为型模式
观察者模式(Observer)(事件发射器)
type EventMap = {
'user.created': { userId: string; email: string };
'order.placed': { orderId: string; total: number };
'payment.failed': { orderId: string; reason: string };
};
class TypedEventBus {
private listeners = new Map<string, Set<Function>>();
on<K extends keyof EventMap>(
event: K,
listener: (data: EventMap[K]) => void
): () => void {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set());
}
this.listeners.get(event)!.add(listener);
// 返回取消订阅函数
return () => this.listeners.get(event)?.delete(listener);
}
emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void {
this.listeners.get(event)?.forEach(listener => {
listener(data);
});
}
}
const bus = new TypedEventBus();
// 订阅(类型安全!)
const unsubscribe = bus.on('user.created', ({ userId, email }) => {
sendWelcomeEmail(email);
});
// 发射
bus.emit('user.created', { userId: '123', email: 'alice@example.com' });
// 清理
unsubscribe();
策略模式(Strategy)
定义一系列算法,使它们可以互换:
interface SortStrategy<T> {
sort(data: T[]): T[];
}
class QuickSort<T> implements SortStrategy<T> {
sort(data: T[]): T[] {
return [...data].sort(); // 简化
}
}
class MergeSort<T> implements SortStrategy<T> {
sort(data: T[]): T[] {
// 归并排序实现
return [...data].sort();
}
}
class DataProcessor<T> {
constructor(private strategy: SortStrategy<T>) {}
setStrategy(strategy: SortStrategy<T>) {
this.strategy = strategy;
}
process(data: T[]): T[] {
return this.strategy.sort(data);
}
}
// 运行时切换算法
const processor = new DataProcessor(new QuickSort<number>());
processor.process([3, 1, 4, 1, 5]);
// 对于大数据集,切换到归并排序
if (data.length > 10000) {
processor.setStrategy(new MergeSort<number>());
}
仓库模式(Repository Pattern)
通过接口抽象数据访问:
interface UserRepository {
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
save(user: User): Promise<User>;
delete(id: string): Promise<void>;
}
// PostgreSQL 实现
class PgUserRepository implements UserRepository {
constructor(private pool: Pool) {}
async findById(id: string) {
const result = await this.pool.query(
'SELECT * FROM users WHERE id = $1', [id]
);
return result.rows[0] ?? null;
}
async findByEmail(email: string) {
const result = await this.pool.query(
'SELECT * FROM users WHERE email = $1', [email]
);
return result.rows[0] ?? null;
}
async save(user: User) {
const result = await this.pool.query(
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
[user.name, user.email]
);
return result.rows[0];
}
async delete(id: string) {
await this.pool.query('DELETE FROM users WHERE id = $1', [id]);
}
}
// 用于测试的内存实现!
class InMemoryUserRepository implements UserRepository {
private users = new Map<string, User>();
async findById(id: string) {
return this.users.get(id) ?? null;
}
async findByEmail(email: string) {
return [...this.users.values()].find(u => u.email === email) ?? null;
}
async save(user: User) {
const saved = { ...user, id: user.id ?? crypto.randomUUID() };
this.users.set(saved.id, saved);
return saved;
}
async delete(id: string) {
this.users.delete(id);
}
}
// 服务使用接口——不知道具体实现
class UserService {
constructor(private users: UserRepository) {}
async register(email: string, password: string): Promise<User> {
const existing = await this.users.findByEmail(email);
if (existing) throw new Error('Email already registered');
return this.users.save({ email, passwordHash: hashPassword(password) });
}
}
// 生产环境
const userService = new UserService(new PgUserRepository(pool));
// 测试——快速,无需数据库
const userService = new UserService(new InMemoryUserRepository());
应避免的反模式
// ❌ 上帝对象——一个类做所有事
class Application {
handleLogin() { ... }
sendEmail() { ... }
processPayment() { ... }
generatePDF() { ... }
// 还有 50 多个方法...
}
// ✅ 单一职责——每个类只有一个职责
// ❌ 贫血领域模型——对象只是数据容器
class User {
name: string;
email: string;
// 没有行为——所有逻辑都在 UserService 中
}
// ✅ 富领域模型——行为与数据共存
class User {
private passwordHash: string;
verifyPassword(password: string): boolean {
return bcrypt.compare(password, this.passwordHash);
}
changeEmail(newEmail: string): void {
if (!isValidEmail(newEmail)) throw new Error('Invalid email');
this.email = newEmail;
this.emit('email.changed', { userId: this.id });
}
}
→ 使用 JSON 查看器 可视化和检查复杂数据结构。