TypeScript 设计模式:高级进阶与实例
\n\n使用 TypeScript 开发复杂应用不仅需要掌握语法,更需要构建灵活、可扩展的架构。GoF(四人帮)设计模式仍是黄金标准,但在高级阶段,其应用会更加精妙。本文将深入剖析四种强大的模式——Bridge、Visitor、State 和 Strategy,并附上 TypeScript 实战示例。您将学习如何利用强类型、泛型和接口来实现这些模式。
\n\n1. Bridge:分离抽象与实现
\n\nBridge(桥接)模式将抽象与其实现分离,使两者可以独立变化。当功能有多种变体且可以相互组合时,该模式尤为实用。
\n\n示例: 在不同图形 API(Canvas 和 SVG)中渲染图形的系统。
\n\n// 实现(Implementation)\ninterface Renderer {\n renderCircle(radius: number): void;\n renderSquare(side: number): void;\n}\n\nclass CanvasRenderer implements Renderer {\n renderCircle(radius: number): void {\n console.log(`Canvas: 绘制半径为 ${radius} 的圆`);\n }\n renderSquare(side: number): void {\n console.log(`Canvas: 绘制边长为 ${side} 的正方形`);\n }\n}\n\nclass SVGRenderer implements Renderer {\n renderCircle(radius: number): void {\n console.log(`SVG: <circle r="${radius}" />`);\n }\n renderSquare(side: number): void {\n console.log(`SVG: <rect width="${side}" height="${side}" />`);\n }\n}\n\n// 抽象(Abstraction)\nabstract class Shape {\n protected renderer: Renderer;\n\n constructor(renderer: Renderer) {\n this.renderer = renderer;\n }\n\n abstract draw(): void;\n}\n\nclass Circle extends Shape {\n private radius: number;\n\n constructor(renderer: Renderer, radius: number) {\n super(renderer);\n this.radius = radius;\n }\n\n draw(): void {\n this.renderer.renderCircle(this.radius);\n }\n}\n\nclass Square extends Shape {\n private side: number;\n\n constructor(renderer: Renderer, side: number) {\n super(renderer);\n this.side = side;\n }\n\n draw(): void {\n this.renderer.renderSquare(this.side);\n }\n}\n\n// 使用示例\nconst canvasCircle = new Circle(new CanvasRenderer(), 10);\ncanvasCircle.draw(); // Canvas: 绘制半径为 10 的圆\n\nconst svgSquare = new Square(new SVGRenderer(), 5);\nsvgSquare.draw(); // SVG: <rect width="5" height="5" />\n\n关键特性: TypeScript 确保所有实现都遵循 Renderer 契约。添加新的图形类型或新的渲染器不会破坏现有代码。
2. Visitor:在不修改类的情况下遍历复杂结构
\n\nVisitor(访问者)模式允许在不修改对象类的情况下为其添加新操作。这是处理树形结构、AST(抽象语法树)或组件层次结构的理想方案。
\n\n示例: 将文档节点导出为不同格式(JSON、XML)的系统。
\n\n// 元素(Elements)\ninterface DocumentNode {\n accept(visitor: Visitor): void;\n}\n\nclass TextNode implements DocumentNode {\n constructor(public content: string) {}\n\n accept(visitor: Visitor): void {\n visitor.visitTextNode(this);\n }\n}\n\nclass ImageNode implements DocumentNode {\n constructor(public src: string, public alt: string) {}\n\n accept(visitor: Visitor): void {\n visitor.visitImageNode(this);\n }\n}\n\n// 访问者(Visitor)\ninterface Visitor {\n visitTextNode(node: TextNode): void;\n visitImageNode(node: ImageNode): void;\n}\n\nclass JSONExporter implements Visitor {\n private p