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();
相关推荐
前端大卫14 分钟前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘30 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare31 分钟前
浅浅看一下设计模式
前端
Lee川34 分钟前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人1 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼1 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端