news 2026/6/15 18:29:00

TypeScript 设计模式:七大结构型模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TypeScript 设计模式:七大结构型模式

结构型设计模式主要用于优化类与对象之间的组合关系,通过灵活组合、包装、拆分现有对象,解决接口不兼容、功能扩展、系统解耦、层级管理、内存优化等问题。这类模式不聚焦对象创建,而是侧重如何组织代码结构,让复杂系统变得简洁、灵活、易维护。

经典结构型模式共包含七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。下文结合 TypeScript 语言,从核心思想、适用场景、优缺点、完整代码、代码解析逐一讲解,所有代码严格遵循统一编码格式规范。


一、适配器模式

1. 核心思想

适配器模式也叫转换器模式,核心是创建一个中间适配类,将原有不兼容的接口进行转换,让原本无法协同工作的类正常交互。它不会修改原有业务代码,仅通过中间层做格式、方法名、参数的适配,分为对象适配器与类适配器,TS 开发中对象适配器最为常用。

2. 适用场景

  1. 对接老旧系统、历史接口、第三方 SDK,新旧接口规范不一致;
  2. 项目迭代升级,新业务接口与旧代码无法直接兼容;
  3. 需要复用现有类,但类提供的方法和当前系统要求的接口不匹配。

3. 优缺点

  • 优点:隔离新旧代码、无需修改原有逻辑、提升代码复用性、解耦性强;
  • 缺点:增加额外适配类,轻微提升代码复杂度;过多使用会让整体结构变得混乱。

4. 代码实现

// 旧系统接口(原有类,无法修改) class Old_Service { public Old_Receive_Data(): void { console.log("旧接口:接收传统格式数据"); } } // 新系统目标接口(当前业务统一规范) interface New_Target_Interface { Receive_Msg(): void; } // 适配器类:衔接新旧接口 class Service_Adapter implements New_Target_Interface { private old_service: Old_Service; constructor(service: Old_Service) { this.old_service = service; } public Receive_Msg(): void { // 调用旧接口方法,完成适配转换 this.old_service.Old_Receive_Data(); } } // 测试调用 let old_service = new Old_Service(); let adapter: New_Target_Interface = new Service_Adapter(old_service); adapter.Receive_Msg();

5. 代码说明

  1. 代码缩进统一为 4 个空格,代码块{紧跟行尾,}独占一行;
  2. 赋值、关系运算符前后均添加空格,逗号后补充空格,符合格式要求;
  3. 外部仅依赖新接口,旧系统逻辑被完全隔离,后续替换旧服务也无需改动业务代码。

二、装饰器模式

1. 核心思想

不修改原类代码、不使用继承的前提下,动态地为对象叠加额外功能。它采用层层包装的思路,支持多层功能组合,比静态继承更加灵活,是功能扩展的常用方案。

2. 适用场景

  1. 需要为对象动态、灵活地添加附加功能,且功能可随时撤销、组合;
  2. 类功能繁多,使用继承会导致子类数量爆炸;
  3. 统一主体功能,不同场景叠加不同附加能力(如日志、权限、校验、附加业务逻辑)。

3. 优缺点

  • 优点:遵循开闭原则、功能组合灵活、多层扩展互不影响、拆分单一职责;
  • 缺点:多层装饰后代码层级变深,排错与调试难度增加。

4. 代码实现

// 抽象主体接口 interface Drink { Get_Price(): number; Get_Name(): string; } // 基础主体类:原味饮品 class Base_Drink implements Drink { public Get_Price(): number { return 8; } public Get_Name(): string { return "基础饮品"; } } // 抽象装饰器父类 abstract class Drink_Decorator implements Drink { protected drink: Drink; constructor(drink: Drink) { this.drink = drink; } public abstract Get_Price(): number; public abstract Get_Name(): string; } // 具体装饰器:加珍珠 class Pearl_Decorator extends Drink_Decorator { public Get_Price(): number { return this.drink.Get_Price() + 2; } public Get_Name(): string { return this.drink.Get_Name() + " + 珍珠"; } } // 具体装饰器:加冰块 class Ice_Decorator extends Drink_Decorator { public Get_Price(): number { return this.drink.Get_Price() + 1; } public Get_Name(): string { return this.drink.Get_Name() + " + 冰块"; } } // 测试调用 let drink: Drink = new Base_Drink(); drink = new Pearl_Decorator(drink); drink = new Ice_Decorator(drink); console.log(`饮品:${drink.Get_Name()},总价:${drink.Get_Price()}`);

5. 代码说明

  1. 所有方法、类命名采用首字母大写 + 下划线分隔;
  2. 装饰器嵌套包装主体对象,可自由调整装饰顺序与层数;
  3. 全程没有修改Base_Drink原有代码,完全符合开闭原则。

三、代理模式

1. 核心思想

为目标对象提供一个代理对象,由代理控制对真实对象的访问。所有请求先经过代理,再转发给真实对象,可在请求前后追加通用逻辑,实现访问控制、功能增强。

常见分类:静态代理、动态代理、虚拟代理、远程代理等,前端 / Node 中静态代理使用最广泛。

2. 适用场景

  1. 权限控制:访问真实对象前做身份、权限校验;
  2. 日志埋点、请求统计、性能监控;
  3. 延迟加载:真实对象创建成本高,使用代理延迟实例化;
  4. 请求拦截、限流、缓存处理。

3. 优缺点

  • 优点:统一管控访问入口、真实对象与附加逻辑解耦、职责清晰;
  • 缺点:额外增加代理类,请求链路变长,轻微增加调用开销。

4. 代码实现

// 统一抽象主题接口 interface Request_Handler { Handle_Request(): void; } // 真实业务对象 class Real_Handler implements Request_Handler { public Handle_Request(): void { console.log("真实对象:执行业务核心逻辑"); } } // 代理对象 class Proxy_Handler implements Request_Handler { private real_handler: Real_Handler; constructor() { this.real_handler = new Real_Handler(); } public Handle_Request(): void { console.log("代理对象:前置权限校验"); this.real_handler.Handle_Request(); console.log("代理对象:后置日志记录"); } } // 测试调用 let proxy: Request_Handler = new Proxy_Handler(); proxy.Handle_Request();

5. 代码说明

  1. 代理与真实对象实现同一接口,对外表现完全一致,调用方无感知;
  2. 前置、后置通用逻辑统一放在代理中,核心业务逻辑保留在真实类中,职责分离。

四、外观模式(门面模式)

1. 核心思想

提供一个统一的对外门面入口,封装内部多个复杂子系统,对外隐藏内部繁杂的调用逻辑。客户端只需要和门面类交互,无需关心多个子系统的调用顺序与依赖关系,简化整体使用难度。

2. 适用场景

  1. 系统由多个相互关联的子模块组成,外部调用流程复杂;
  2. 划分层级架构,隔离内外层代码,降低耦合;
  3. 重构老旧复杂系统,用门面统一收口对外接口。

3. 优缺点

  • 优点:简化调用、降低耦合、统一入口、分层清晰;
  • 缺点:门面类职责过重,若设计不合理会变成 “万能类”;新增子系统可能需要修改门面代码。

4. 代码实现

// 子系统 A class Sub_System_A { public Run_A(): void { console.log("子系统 A 执行初始化"); } } // 子系统 B class Sub_System_B { public Run_B(): void { console.log("子系统 B 执行业务处理"); } } // 子系统 C class Sub_System_C { public Run_C(): void { console.log("子系统 C 执行收尾清理"); } } // 外观门面类 class System_Facade { private sys_a: Sub_System_A; private sys_b: Sub_System_B; private sys_c: Sub_System_C; constructor() { this.sys_a = new Sub_System_A(); this.sys_b = new Sub_System_B(); this.sys_c = new Sub_System_C(); } // 统一对外方法,封装调用顺序 public Start_All_System(): void { this.sys_a.Run_A(); this.sys_b.Run_B(); this.sys_c.Run_C(); } } // 测试调用 let facade = new System_Facade(); facade.Start_All_System();

5. 代码说明

  1. 客户端仅调用System_Facade,完全不用感知内部三个子系统;
  2. 子系统内部可独立维护,不影响外部调用逻辑。

五、桥接模式

1. 核心思想

抽象层实现层彻底分离,让两者可以独立扩展变化,避免多层继承导致的类爆炸问题。它使用组合替代继承,把多维度变化拆分为两个独立体系,自由组合使用。

2. 适用场景

  1. 系统存在两个或多个独立变化的维度,且维度之间需要自由组合;
  2. 不希望使用多层继承,控制类的数量;
  3. 需要跨平台、跨类型扩展,抽象与实现需要动态切换。

3. 优缺点

  • 优点:拆分变化维度、扩展性极强、减少子类数量、解耦抽象与实现;
  • 缺点:设计难度提升,需要提前梳理业务的变化维度。

4. 代码实现

// 实现层接口:颜色维度(独立变化维度) interface Color_Type { Show_Color(): void; } class Red_Color implements Color_Type { public Show_Color(): void { console.log("颜色:红色"); } } class Blue_Color implements Color_Type { public Show_Color(): void { console.log("颜色:蓝色"); } } // 抽象层父类:形状维度(另一独立变化维度) abstract class Shape { protected color: Color_Type; constructor(color: Color_Type) { this.color = color; } public abstract Draw_Shape(): void; } // 具体形状:圆形 class Circle_Shape extends Shape { constructor(color: Color_Type) { super(color); } public Draw_Shape(): void { process.stdout.write("绘制圆形,"); this.color.Show_Color(); } } // 具体形状:方形 class Square_Shape extends Shape { constructor(color: Color_Type) { super(color); } public Draw_Shape(): void { process.stdout.write("绘制方形,"); this.color.Show_Color(); } } // 测试调用 let red_circle = new Circle_Shape(new Red_Color()); red_circle.Draw_Shape(); let blue_square = new Square_Shape(new Blue_Color()); blue_square.Draw_Shape();

5. 代码说明

  1. 形状、颜色两个维度完全独立,新增形状或新增颜色互不影响;
  2. 通过构造函数组合两个维度,替代传统多继承结构。

六、组合模式

1. 核心思想

将对象组织成树形层级结构,统一对待单个叶子对象容器组合对象。调用方无需区分节点类型,使用一致的方式遍历、操作整棵树,非常适合层级化场景。

2. 适用场景

  1. 树形结构业务:系统菜单、文件目录、组织架构、权限树;
  2. 需要统一处理整体与部分,忽略节点差异的场景。

3. 优缺点

  • 优点:统一操作接口、灵活构建树形结构、符合树形业务场景;
  • 缺点:如果业务规则复杂,节点类型过多时,约束节点行为会比较困难。

4. 代码实现

// 抽象节点组件 abstract class Tree_Component { protected node_name: string; constructor(name: string) { this.node_name = name; } public abstract Show_Node_Info(): void; } // 叶子节点:最小单元,无子节点 class Leaf_Node extends Tree_Component { public Show_Node_Info(): void { console.log(`叶子节点:${this.node_name}`); } } // 容器节点:可包含子节点 class Container_Node extends Tree_Component { private child_list: Tree_Component[] = []; public Add_Child(node: Tree_Component): void { this.child_list.push(node); } public Show_Node_Info(): void { console.log(`容器节点:${this.node_name}`); for (let i = 0; i < this.child_list.length; i++) { this.child_list[i].Show_Node_Info(); } } } // 测试调用 let root = new Container_Node("根目录"); let folder = new Container_Node("文件夹"); let file_1 = new Leaf_Node("文件1"); let file_2 = new Leaf_Node("文件2"); folder.Add_Child(file_1); root.Add_Child(folder); root.Add_Child(file_2); root.Show_Node_Info();

5. 代码说明

  1. 叶子节点与容器节点继承同一抽象类,对外接口完全一致;
  2. 天然适配文件目录、菜单等树形业务,层级扩展简单。

七、享元模式

1. 核心思想

复用大量重复对象,抽取对象中固定不变的内部状态作为共享数据,将频繁变化的外部状态单独传入,以此减少内存占用、降低对象创建数量。核心是对象复用、池化管理

2. 适用场景

  1. 系统中存在大量相似对象,创建对象会消耗大量内存;
  2. 对象可拆分为「内部固定状态」和「外部可变状态」;
  3. 典型场景:游戏怪物、网页图标、弹窗样式、连接池等。

3. 优缺点

  • 优点:极大减少内存开销、提升性能、复用对象资源;
  • 缺点:需要拆分内外状态,增加代码逻辑;线程并发场景下需要注意对象状态安全。

4. 代码实现

const MAX_POOL_COUNT = 10; // 享元类:存储内部共享状态 class Flyweight_Object { private type_tag: string; constructor(tag: string) { this.type_tag = tag; } // 接收外部可变状态执行业务 public Use_Info(outside_state: string): void { console.log(`共享标识:${this.type_tag},外部状态:${outside_state}`); } } // 享元工厂:负责对象池管理、复用对象 class Flyweight_Factory { private object_pool: Map<string, Flyweight_Object> = new Map(); public Get_Object(tag: string): Flyweight_Object { if (!this.object_pool.has(tag)) { this.object_pool.set(tag, new Flyweight_Object(tag)); } return this.object_pool.get(tag)!; } } // 测试调用 let factory = new Flyweight_Factory(); let obj_1 = factory.Get_Object("icon_01"); let obj_2 = factory.Get_Object("icon_01"); obj_1.Use_Info("页面A"); obj_2.Use_Info("页面B"); if (obj_1 == obj_2) { console.log("两个引用指向同一个共享对象"); }

5. 代码说明

  1. 常量MAX_POOL_COUNT全大写 + 下划线命名,符合编码规范;
  2. 工厂统一管理对象池,相同标识的对象只会创建一次,实现复用;
  3. 可变状态通过参数动态传入,不污染共享对象内部数据。

结构型模式综合总结

  1. 适配器:解决接口不兼容,做中间转换;
  2. 装饰器:动态给对象叠加功能,灵活扩展;
  3. 代理:控制对象访问,追加前置 / 后置通用逻辑;
  4. 外观:封装多子系统,提供统一简易调用入口;
  5. 桥接:拆分多维度变化,用组合替代继承,防类爆炸;
  6. 组合:构建树形结构,统一处理整体与局部节点;
  7. 享元:池化复用相似对象,大幅优化内存占用。

在 TypeScript / Node.js 项目开发中,可根据结构特点、扩展需求、性能要求选择对应模式,让代码结构更合理、架构更健壮。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 18:29:00

领域专长:AI时代开发者真正的护城河

领域专长&#xff1a;AI时代开发者真正的护城河 在技术圈&#xff0c;我们常常陷入一种焦虑&#xff1a;框架更新换代太快&#xff0c;语言流行度起起伏伏&#xff0c;如今更是加上了"AI会不会取代程序员"的终极拷问。每当一个像 Devin 这样的AI智能体或者 GPT-5.5 级…

作者头像 李华
网站建设 2026/6/15 18:23:49

重塑声音认知:专业音频分析工具的技术深度解析与实战指南

重塑声音认知&#xff1a;专业音频分析工具的技术深度解析与实战指南 【免费下载链接】voice-pitch-analyzer 项目地址: https://gitcode.com/gh_mirrors/vo/voice-pitch-analyzer 您是否曾好奇自己的声音特质&#xff1f;在音乐训练、语音治疗乃至日常沟通中&#xff…

作者头像 李华
网站建设 2026/6/15 18:22:00

什么是项目管理进度?如何有效把控项目管理进度?

在探讨企业运营与团队协作时&#xff0c;我们经常会遇到一个核心问题&#xff1a;什么是项目管理进度&#xff1f;简单来说&#xff0c;项目管理进度是指对项目各阶段工作的进展情况进行计划、协调、控制和优化的一系列活动。项目管理进度是确保项目在规定时间范围内高效完成的…

作者头像 李华
网站建设 2026/6/15 18:20:02

化工应急段供电零中断:KT3380 无扰动快切改造实战

新疆中泰化学应急段400V系统KT3380无扰动切换技术改造在氯碱化工的生产线上&#xff0c;电解槽的电流一旦中断&#xff0c;不仅意味着当批原料的报废&#xff0c;更可能引发连锁的安全事故。对于像新疆中泰化学阜康能源这样的大型化工企业而言&#xff0c;应急段 400V 供电系统…

作者头像 李华
网站建设 2026/6/15 18:17:58

深入解析I2C中断服务程序与寄存器编程,构建稳健嵌入式通信

1. I2C总线通信的核心机制与中断服务概览在嵌入式系统开发中&#xff0c;I2C总线因其简洁的两线制&#xff08;SDA数据线和SCL时钟线&#xff09;和灵活的多主从架构&#xff0c;成为了连接微控制器与各类传感器、存储器、IO扩展芯片的首选协议。然而&#xff0c;很多开发者仅仅…

作者头像 李华
网站建设 2026/6/15 18:15:55

多模态RAG不是加图就行:工业级跨模态检索架构实战

1. 这不是“加个图片就能搜”的简单功能&#xff0c;而是一套需要重新定义信息流动的系统工程“Multimodal RAG System Architecture”——光看这个标题&#xff0c;很多人第一反应是&#xff1a;哦&#xff0c;就是把文本RAG&#xff08;检索增强生成&#xff09;再塞点图片进…

作者头像 李华