掌握创建型、结构型与行为型设计模式,用 TypeScript 示例学习如何组织类与对象,提高代码可维护性与扩展性。
December 20, 2025 (9mo ago) — last updated June 8, 2026 (3mo ago)
面向对象设计模式:TypeScript 实用指南
掌握创建型、结构型与行为型设计模式,配合 TypeScript 示例与实用重构建议,提升代码可维护性与可扩展性。
← Back to blog
面向对象设计模式:TypeScript 实用指南
通过本指南掌握面向对象设计模式。学习创建型、结构型和行为型模式,并配有清晰、实用的 TypeScript 代码示例,提升代码的可维护性与扩展性。
介绍
面向对象编程中的设计模式是为解决常见设计问题而验证过、可重用的蓝图。它们不是可直接复制粘贴的完整代码,而是可适配的模板,帮助你组织类与对象,让代码更易维护、扩展与测试。
扎实掌握创建型、结构型与行为型模式,能让你与团队成员更清晰地沟通设计意图、安全地重构遗留代码,并为每个架构问题选择合适的工具。
设计模式为何重要
没有设计模式的编码往往会导致纠结缠绕、难以扩展的代码库。设计模式就像大厨的食谱书:经过验证的配方,能在不同项目中复用并产生一致、可维护的结果。

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

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

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。
常见问题解答(Q&A)
我应该先学哪些设计模式?
先专注于 5–7 个核心模式:Singleton、Factory、Adapter、Decorator、Observer、Strategy。理解每个模式要解决的问题和权衡,掌握后再扩展到其他模式。
何时应避免使用设计模式?
避免增加复杂性但无实质收益的模式。不要“以防万一”地引入模式。遵循 YAGNI:当且仅当存在明确且当前的问题时才添加模式。
如何在 TypeScript 项目中实践这些模式?
优先用接口与类型定义清晰边界,用依赖注入减少全局状态,并用单元测试验证替换算法或装饰器的行为。我们的网站有相关的代码审计与重构服务,能帮助团队把这些原则嵌入工作流https://cleancodeguy.com。
在 Clean Code Guy,我们通过将基础原则嵌入团队工作流,帮助团队构建经久耐用的软件。了解我们的代码审计和面向 AI 的重构如何让你的团队自信交付,请访问 https://cleancodeguy.com。
AI编写代码。您让它持久。
在AI加速的时代,干净代码不仅仅是好的实践 — 它是能够扩展的系统与在自己的重量下崩溃的代码库之间的区别。