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();
相关推荐
昔人'24 分钟前
`list-style-type: decimal-leading-zero;`在有序列表`<ol></ol>` 中将零添加到一位数前面
前端·javascript·html
岁月宁静6 小时前
深度定制:在 Vue 3.5 应用中集成流式 AI 写作助手的实践
前端·vue.js·人工智能
心易行者6 小时前
10天!前端用coze,后端用Trae IDE+Claude Code从0开始构建到平台上线
前端
saadiya~7 小时前
ECharts 实时数据平滑更新实践(含 WebSocket 模拟)
前端·javascript·echarts
fruge7 小时前
前端三驾马车(HTML/CSS/JS)核心概念深度解析
前端·css·html
百锦再7 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
烛阴7 小时前
Lua 模块的完整入门指南
前端·lua
Mr_WangAndy8 小时前
C++设计模式_行为型模式_策略模式Strategy
c++·设计模式·策略模式·依赖倒置原则
浪里行舟8 小时前
国产OCR双雄对决?PaddleOCR-VL与DeepSeek-OCR全面解析
前端·后端
LoveXming8 小时前
Chapter11—适配器模式
c++·设计模式·适配器模式·开闭原则