TS手写设计模式②:7个结构型模式写透,打造你系统的“外骨骼”

15 阅读3分钟

👉 项目地址:GitHub - cynthiaCh/design-patterns-ts

本文是《TS手写设计模式》系列的第二篇,我们将一起手写实现 7个结构型设计模式,并结合 DSL 系统与中后台场景讲解落地思路。

结构型模式关注“如何优雅地组合类与对象”,适合构建 灵活、可扩展、易维护的系统骨架

🧠 什么是结构型模式?

结构型模式解决的是:

✅ 如何组织多个类、对象之间的关系,从而实现系统功能的组合复用与灵活切换。

在前端实践中,它们广泛应用于:

  • 表单渲染器、插件系统
  • 老系统兼容、Schema 转换
  • 复杂流程封装、事件处理增强

✅ 一、装饰器模式(Decorator Pattern)

不改变原有结构,为对象动态添加功能。

🎯 适用场景

  • 字段增强(如加校验、只读、placeholder)
  • 中间件式渲染增强(如高亮、调试日志)

✏️ TS 实现

interface Field {
  render(): string
}

class InputField implements Field {
  render() { return '<input />' }
}

class RequiredDecorator implements Field {
  constructor(private field: Field) {}
  render() {
    return this.field.render() + ' *'
  }
}

🧩 在 DSL 中怎么用?

给字段动态加功能,不污染原始类:

const baseField = new InputField()
const fieldWithRequired = new RequiredDecorator(baseField)
console.log(fieldWithRequired.render()) // <input /> *

支持组合多个装饰器,形成“插件链”!

✅ 二、适配器模式(Adapter Pattern)

兼容旧接口,让新代码复用旧逻辑。

🎯 适用场景

  • 接入第三方 UI 库(如旧版 el-input)
  • Schema 转换、组件兼容

✏️ TS 实现

interface NewField {
  render(): string
}

class OldComponent {
  show() { return 'old html' }
}

class FieldAdapter implements NewField {
  constructor(private legacy: OldComponent) {}
  render() {
    return this.legacy.show()
  }
}

🧩 在 DSL 中怎么用?

renderField(new FieldAdapter(new OldComponent()))

👉 在不重构旧组件的前提下,平滑接入到新版系统。

✅ 三、外观模式(Facade Pattern)

简化调用接口,隐藏系统复杂性。

🎯 适用场景

  • 初始化流程封装(DSL 引擎启动器)
  • 表单构造器/渲染器调用封装

✏️ TS 实现

class Compiler {
  compile() {/*...*/} transform() {/*...*/} validate() {/*...*/}
}

class DSLFacade {
  private compiler = new Compiler()
  build() {
    this.compiler.compile()
    this.compiler.transform()
    this.compiler.validate()
  }
}

🧩 在 DSL 中怎么用?

const dsl = new DSLFacade()
dsl.build()

👉 外观模式让复杂逻辑只暴露一个简洁入口,用户无需关心底层细节,极大提升开发体验。

✅ 四、代理模式(Proxy Pattern)

控制对象访问,可添加权限/缓存/懒加载等逻辑。

应用示例:

class FieldProxy implements Field {
  constructor(private realField: Field) {}
  render() {
    console.log('Log before render')
    return this.realField.render()
  }
}

👉 在 DSL 中常用于字段渲染日志、性能监控、权限校验。

✅ 五、组合模式(Composite Pattern)

将对象组合成树状结构,统一处理单个对象和组合对象。

应用示例:

interface Component { render(): string }

class FieldGroup implements Component {
  constructor(private children: Component[]) {}
  render() {
    return this.children.map(c => c.render()).join('\n')
  }
}

👉 表单分组、多字段嵌套的渲染器就是组合模式的最佳实践。

✅ 六、桥接模式(Bridge Pattern)

将抽象与实现分离,使它们可以独立变化。

应用示例:

interface Theme { getStyle(): string }
class DarkTheme implements Theme { getStyle() { return 'dark' } }

abstract class Field {
  constructor(protected theme: Theme) {}
  abstract render(): string
}

class SelectField extends Field {
  render() { return `<select class="${this.theme.getStyle()}">...</select>` }
}

👉 用于主题系统、地域配置的样式与结构分离。

✅ 七、享元模式(Flyweight Pattern)

共享细粒度对象,降低内存使用。

应用示例:

class FieldFactory {
  private static pool: Record<string, Field> = {}

  static get(type: string): Field {
    if (!this.pool[type]) {
      this.pool[type] = new InputField()
    }
    return this.pool[type]
  }
}

👉 在大规模字段动态渲染中减少重复对象创建,提升性能。

🧠 总结与对比

模式关键词典型用途
装饰器动态增强字段插件、验证器、渲染增强
适配器接口转换接入旧组件/第三方 API
外观简化使用系统初始化、表单构建
代理访问控制日志记录、懒加载、权限判断
组合树形结构字段组、嵌套布局
桥接抽象分离样式解耦、主题/地域切换
享元对象复用提高性能、内存优化

🚀 下一篇预告:行为型模式!

下一篇我们将进入「行为型模式」部分,包括:

  • 策略模式(值处理策略)
  • 观察者模式(事件系统)
  • 责任链模式(校验链)
  • 状态模式、命令模式、解释器模式……

📌 项目源码持续更新中 👉 GitHub
写给想深入理解系统设计的你!