23种设计模式之建造者模式

特性

虽然也是为了创建对象,但是相比于工厂模式,该模式更关注创建过程及细节。

基础术语

构建层

定义与作用

构建层是指 负责对象创建过程部分 的代码。

它定义了创建对象的步骤和方法,但不直接指定对象的具体表示形式。

构建层所拥有的角色

  1. 抽象构建者(Abstract Builder) :定义创建对象各个部件的接口。
  2. 具体构建者(Concrete Builder) :实现抽象构建者接口,逐步构建复杂对象的各个部件。
  3. 指挥者(Director) :使用构建者来创建对象,通常不依赖于具体构建者的实现,而是通过抽象构建者接口与构建者交互。

表示层

表示层是指对象的最终表示形式或结构。它定义了对象的内部状态和行为,但不直接参与对象的创建过程。表示层通常是一个独立的类,用于存储对象的属性和方法。

优点

  1. 分离构建过程与表示:将复杂的构建过程与最终的表示分离,使得可以使用不同的构建过程形成不同的最终表示。
  2. 逐步构建对象:允许逐步构建复杂对象,便于添加新的构建步骤。
  3. 代码复用:通过构建器类复用构建逻辑,减少重复代码。
  4. 灵活性:可以轻松地创建不同的对象表示,只需实现不同的构建器类。

缺点

  1. 增加代码复杂度:引入了额外的类,使得代码结构变得更加复杂。
  2. 可能产生过多的类:如果需要创建多种不同的对象表示,可能会产生过多的构建器类。

定义

将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示。

可以用不同组合或顺序建造出不同意义的对象,通常使用者并不需要知道建造的细节,通常使用链式调用 来进行建造过程,最后调用build方法来生成最终对象。

应用场景

  1. 构建复杂的对象或界面组件
  2. 在需要分步骤创建对象时。
  3. 当需要为同一对象创建多种不同的表示时。

如何实现

  1. 实现表示层 类:主要用于描述最终产物的各种行为。
  2. 构建抽象建造者:主要用于确定构建功能模块的类型,并且创建表示层类的实例。

通常用一个有方法及属性但无具体实现的父类来表示。在ts可以使用接口类来代替父类。

对于一些与建造无关的方法可以将实现放置在父类,剩余的应该下放到子类实现。

会在构造函数中进行表示层类的实例的创建及存储。

  1. 构建具体建造者:抽象建造者的子类,相当于对抽象建造者描述的创建过程中各个功能模块进行具体实现。

每个功能模块应该返回 this ,方便后续链式调用

  1. 构建指挥者:主要集成了进行各种类型的对象构建的方法。

该步骤可以省略,直接合并至步骤 5

  1. 客户端使用:用于构建整体对象并使用,完成业务需求的实现

示例

动态表单生成器

需求说明

构建一个用户注册表单,包含基础信息、地址信息、偏好设置等模块,且不同场景下模块组合可能变化。

构建步骤

  1. 产出表示层类:表单配置对象,用于进行表单的各种行为的承载
typescript 复制代码
class FormConfig {
  constructor() {
    this.fields = [];
  }
  addField(type, label, required = false) {
    this.fields.push({ type, label, required });
  }
  render() {
    return this.fields.map(field => <>表单项</>);
  }
}
  1. 构建抽象建造者
javascript 复制代码
class FormBuilder {
  constructor() {
    this.form = new FormConfig();
  }
  buildBasicInfo() {}
  buildAddress() {}
  buildPreferences() {}
  getForm() {
    return this.form;
  }
}
  1. 构建具体建造者
kotlin 复制代码
class RegistrationFormBuilder extends FormBuilder {
  buildBasicInfo() {
    this.form.addField('text', '用户名', true);
    this.form.addField('email', '邮箱', true);
    return this; // 支持链式调用
  }

  buildAddress() {
    this.form.addField('text', '街道');
    this.form.addField('text', '城市');
    return this;
  }

  buildPreferences() {
    this.form.addField('checkbox', '订阅新闻');
    return this;
  }
}
  1. 创建指挥者
kotlin 复制代码
class FormDirector {
  constructor(builder) {
    this.builder = builder;
  }

  buildFullForm() {
    return this.builder
      .buildBasicInfo()
      .buildAddress()
      .buildPreferences()
      .getForm();
  }

  buildMinimalForm() {
    return this.builder
      .buildBasicInfo()
      .getForm();
  }
}
  1. 客户端使用
ini 复制代码
// 创建建造者
const builder = new RegistrationFormBuilder();

// 方式1:直接使用建造者(灵活自定步骤)
const customForm = builder
  .buildBasicInfo()
  .buildPreferences()
  .getForm();


// 方式2:通过指挥者(标准化流程)
const director = new FormDirector(builder);
const fullForm = director.buildFullForm();
相关推荐
踩着两条虫5 小时前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava
和沐阳学逆向6 小时前
我现在怎么用 CC Switch 管中转站,顺手拿 Codex 举个例子
开发语言·javascript·ecmascript
swipe6 小时前
AI 应用里的 Memory,不是“保存聊天记录”,而是管理上下文预算
前端·llm·agent
慧一居士6 小时前
nuxt3 项目和nuxt4 项目区别和对比
前端·vue.js
威联通安全存储7 小时前
破除“重前端、轻底层”的数字幻象:如何夯实工业数据的物理底座
前端·python
inksci7 小时前
Js生成安全随机数
前端·微信小程序
吴声子夜歌7 小时前
TypeScript——泛型
前端·git·typescript
kgduu8 小时前
js之客户端存储
javascript·数据库·oracle
四千岁8 小时前
2026 最新版:WSL + Ubuntu 全栈开发环境,一篇搞定!
javascript·node.js
猩猩程序员8 小时前
Pretext:一个绕过 DOM 的纯 JavaScript 排版引擎
前端