通过本指南掌握面向对象设计模式。学习创建型、结构型和行为型模式,并配有清晰且实用的代码示例,提升你的技能。
December 20, 2025 (4mo ago)
面向对象设计模式实用指南
通过本指南掌握面向对象设计模式。学习创建型、结构型和行为型模式,并配有清晰且实用的代码示例,提升你的技能。
← Back to blog
面向对象设计模式实用指南
通过本指南掌握面向对象设计模式。学习创建型、结构型和行为型模式,并配有清晰、实用的代码示例,提升你的技能。
介绍
面向对象编程中的设计模式是为解决常见设计问题而验证过、可重用的蓝图。它们并不是可以直接复制粘贴的代码;而是可适配的模板,帮助你组织类和对象,使代码更易于维护、扩展和测试。
对常见模式——创建型、结构型和行为型——的扎实掌握,可以让你与团队成员清晰地沟通设计意图、安全地重构遗留代码,并为每个架构问题选择合适的工具。
什么是面向对象编程中的设计模式
有没有尝试过在没有计划的情况下构建复杂的东西?没有设计模式的编码可能会导致一个纠结缠绕、难以扩展和维护的代码库。设计模式就像大厨的食谱书:经过验证的配方,适配使用以产生一致且易维护的结果。

开发者的共同语言
模式最有价值的好处之一是它提供了共同的词汇。说出“Factory”或“Singleton”,有经验的开发者立刻能理解意图和高层结构,这加快了协作和架构决策。
“Design Patterns: Elements of Reusable Object-Oriented Software”,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 于 1994 年出版,编录了 23 个基础模式,这些仍然是 OOP 从业者的必读内容2。这些模式建立在早期的学术工作之上,展示了在大型项目中可测量的生产力和重用益处1。
设计模式不是可以直接转换为代码的完成设计。它是一个描述或模板,说明如何在许多不同情况下解决一个问题。
熟练掌握多态和继承等核心 OOP 原则,有助于你更有效地应用模式。若需实用复习,请参见我们比较 polymorphism vs inheritance 的指南。
设计模式的三大核心类别
Gang of Four(四人帮)将模式组织为三类:创建型、结构型和行为型。了解这些类别可以帮助你快速为问题选择正确的方法。

OOP 设计模式类别概述
| 模式类别 | 核心目的 | 常见示例 |
|---|---|---|
| 创建型 | 管理并抽象对象创建 | Factory、Builder、Singleton、Prototype |
| 结构型 | 将类和对象组合成更大且灵活的结构 | Adapter、Decorator、Facade、Composite |
| 行为型 | 定义对象如何交互与通信 | Observer、Strategy、Command、Iterator |
创建型模式:构建专家
创建型模式控制对象的创建方式,以避免客户端代码与具体类紧密耦合。它们隐藏创建逻辑,增加灵活性,并让你管理实例化(例如用 Singleton 强制单一实例)。
结构型模式:架构粘合剂
结构型模式帮助你将对象组装成更大的系统。它们简化组件之间的关系,使你可以更改某些部分而不破坏整个系统。像 Adapter 这样的模式允许不兼容的接口协作,这在集成第三方库时非常宝贵。
结构型模式通过识别实体之间实现关系的简单方式来简化系统设计。
行为型模式:通信指挥官
行为型模式管理对象的交互和责任分配。它们创建了干净的通信通道——Observer 用于事件驱动通知,Strategy 用于在不修改客户端的情况下替换算法。
通过谨慎管理通信路径,你可以减少依赖,使代码库更容易理解和维护。
使用创建型模式创建对象
创建型模式在对象创建周围引入一层抽象,这样你就可以在不更改客户端代码的情况下替换实现。下面是两个实用的 TypeScript 示例:Singleton 和 Factory Method。

Singleton 模式:确保唯一实例
Singleton 确保一个类只有一个实例并提供全局访问点。它适用于共享资源,如数据库连接或日志记录器,但它可能引入全局状态,增加测试和依赖管理的复杂性3。
示例:一个用于数据库连接的 TypeScript Singleton。
class DatabaseConnection {
private static instance: DatabaseConnection;
private constructor() {
// A private constructor prevents external 'new' calls
console.log("Connecting to the database...");
}
public static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
public query(sql: string): void {
console.log(`Executing query: ${sql}`);
}
}
// Usage
const db1 = DatabaseConnection.getInstance();
const db2 = DatabaseConnection.getInstance();
db1.query("SELECT * FROM users");
console.log(db1 === db2); // true
Singleton 的权衡:对真正的全局资源可以使用 Singleton,但更推荐使用依赖注入以获得更好的可测试性和模块化3。
Factory Method:让子类决定创建什么
Factory Method 定义了创建对象的接口,而由子类决定实例化哪个具体产品。它将客户端代码与具体类解耦,使系统更容易扩展。
示例:在 TypeScript 中渲染操作系统特定的按钮。
interface Button {
render(): void;
onClick(f: () => void): void;
}
class WindowsButton implements Button {
render() { console.log("Rendering a button in Windows style."); }
onClick(f: () => void) { console.log("Windows button click event."); f(); }
}
class MacButton implements Button {
render() { console.log("Rendering a button in macOS style."); }
onClick(f: () => void) { console.log("Mac button click event."); f(); }
}
abstract class Dialog {
abstract createButton(): Button;
render() {
const okButton = this.createButton();
okButton.render();
}
}
class WindowsDialog extends Dialog {
createButton(): Button { return new WindowsButton(); }
}
class MacDialog extends Dialog {
createButton(): Button { return new MacButton(); }
}
// Client
const os: string = "windows";
let dialog: Dialog;
if (os === "windows") dialog = new WindowsDialog(); else dialog = new MacDialog();
dialog.render();
Factory Method 使创建者不需要知道具体产品,从而使添加像 LinuxDialog 这样的新类型变得简单直接。
使用结构型模式构建灵活系统
结构型模式帮助你将对象组合成健壮且可适配的系统。两个实用的选择是 Adapter 和 Decorator。

Adapter 模式:桥接不兼容接口
Adapter 将不兼容的接口包装为符合你系统期望的接口。这样可以避免对遗留代码进行侵入式更改。
示例:将 ModernLogger 适配到现有的 ILogger 接口。
class ModernLogger {
public logInfo(message: string): void {
console.log(`[INFO]: ${message}`);
}
}
interface ILogger { log(message: string): void; }
class LoggerAdapter implements ILogger {
private modernLogger: ModernLogger;
constructor() { this.modernLogger = new ModernLogger(); }
public log(message: string): void { this.modernLogger.logInfo(message); }
}
const logger: ILogger = new LoggerAdapter();
logger.log("User logged in successfully.");
Decorator 模式:动态添加功能
Decorator 通过包装对象在运行时添加职责。它比子类化更灵活,并遵循单一职责原则。
示例:组合一个带有可选附加项的订阅。
interface Subscription { getDescription(): string; getCost(): number; }
class BasicSubscription implements Subscription {
getDescription(): string { return "Basic Plan"; }
getCost(): number { return 10; }
}
abstract class SubscriptionDecorator implements Subscription {
protected subscription: Subscription;
constructor(subscription: Subscription) { this.subscription = subscription; }
abstract getDescription(): string;
abstract getCost(): number;
}
class PremiumSupportDecorator extends SubscriptionDecorator {
getDescription(): string { return `${this.subscription.getDescription()}, Premium Support`; }
getCost(): number { return this.subscription.getCost() + 5; }
}
class CloudStorageDecorator extends SubscriptionDecorator {
getDescription(): string { return `${this.subscription.getDescription()}, 1TB Cloud Storage`; }
getCost(): number { return this.subscription.getCost() + 7; }
}
let mySubscription: Subscription = new BasicSubscription();
mySubscription = new PremiumSupportDecorator(mySubscription);
mySubscription = new CloudStorageDecorator(mySubscription);
console.log(mySubscription.getDescription());
console.log(mySubscription.getCost());
这种组合式方法使特性模块化且易于测试。
使用行为型模式管理交互
行为型模式组织对象通信,使系统保持灵活和可维护。两个核心示例是 Observer 和 Strategy。
Observer 模式:通知感兴趣的方
Observer 建立一对多关系,以便当 Subject 状态改变时,Observers 会自动收到通知。它非常适合事件驱动的系统。
示例:一个简单的通知服务。
interface Subject { attach(observer: Observer): void; detach(observer: Observer): void; notify(): void; }
interface Observer { update(subject: Subject): void; }
class NotificationService implements Subject {
public state: string = '';
private observers: Observer[] = [];
attach(observer: Observer): void { this.observers.push(observer); }
detach(observer: Observer): void { const i = this.observers.indexOf(observer); if (i !== -1) this.observers.splice(i, 1); }
notify(): void { for (const o of this.observers) o.update(this); }
public createNewPost(title: string): void { this.state = `New Post: ${title}`; console.log(`\nNotificationService: A new post was created.`); this.notify(); }
}
class EmailNotifier implements Observer { public update(subject: Subject): void { if (subject instanceof NotificationService) console.log(`EmailNotifier: Sending email about "${subject.state}"`); } }
class PushNotifier implements Observer { public update(subject: Subject): void { if (subject instanceof NotificationService) console.log(`PushNotifier: Sending push notification for "${subject.state}"`); } }
const notificationService = new NotificationService();
const emailer = new EmailNotifier();
const pusher = new PushNotifier();
notificationService.attach(emailer);
notificationService.attach(pusher);
notificationService.createNewPost("Understanding Observer Pattern");
notificationService.detach(pusher);
notificationService.createNewPost("Why Strategy is Awesome");
Observer 产生了松耦合的设计:Subjects 不需要知道它们所通知的具体 Observers。
Strategy 模式:封装算法
Strategy 允许你在运行时替换算法,避免大量条件分支。它符合开闭原则,通过允许新增策略而不修改现有代码来实现扩展性4。
示例:购物车的支付策略。
interface PaymentStrategy { pay(amount: number): void; }
class CreditCardStrategy implements PaymentStrategy { pay(amount: number): void { console.log(`Paying $${amount} with Credit Card.`); } }
class PayPalStrategy implements PaymentStrategy { pay(amount: number): void { console.log(`Paying $${amount} via PayPal.`); } }
class ShoppingCart {
private paymentStrategy: PaymentStrategy;
constructor(strategy: PaymentStrategy) { this.paymentStrategy = strategy; }
public setPaymentStrategy(strategy: PaymentStrategy) { this.paymentStrategy = strategy; }
public checkout(amount: number): void { this.paymentStrategy.pay(amount); }
}
const cart = new ShoppingCart(new CreditCardStrategy());
cart.checkout(150);
cart.setPaymentStrategy(new PayPalStrategy());
cart.checkout(150);
Strategy 消除了条件复杂性,使系统更易于扩展。
常见的设计陷阱与重构策略
选择一个模式只是战斗的一半。避免像 God Object(上帝对象)这样的反模式,它囤积职责并违反单一职责原则。注意代码异味——冗长的方法、过多依赖或怪物类,并通过有纪律的重构来解决它们。
重构旨在在不改变外部行为的前提下改善内部结构。这是你安全驯服遗留系统的方法。
重构为 Strategy 模式
大型的 switch 或冗长的 if/else 链是经典的代码异味。通过将可变行为提取到 Strategy 接口和具体策略类中进行重构。用对所选策略方法的单次调用替换条件分支。此更改改善了可扩展性、可测试性,并更符合 SOLID 原则4。
回答关于 OOP 设计模式的常见问题
我应该学习多少种设计模式?
先专注于 5–7 个核心模式:Singleton、Factory、Adapter、Decorator、Observer 和 Strategy。了解每个模式解决的问题;一旦你掌握了这些,学习额外的模式会容易得多。
何时应该避免使用设计模式?
避免那些增加复杂性但并不能解决实际问题的模式。不要“以防万一”地引入模式。遵循 YAGNI:当且仅当存在明确且当前的问题时才添加模式。
我可以在函数式编程中使用设计模式吗?
可以。许多模式自然地映射到函数式技术。Strategy 可以用函数参数表示,Decorator 可以是高阶函数。关键是应用其背后的原则,而不是僵化地复制 OOP 形式。
在 Clean Code Guy,我们通过将基础原则嵌入团队工作流,帮助团队构建经久耐用的软件。了解我们的代码审计和面向 AI 的重构如何让你的团队自信交付,请访问 https://cleancodeguy.com。
AI编写代码。您让它持久。
在AI加速的时代,干净代码不仅仅是好的实践 — 它是能够扩展的系统与在自己的重量下崩溃的代码库之间的区别。