特性
虽然也是为了创建对象,但是相比于工厂模式,该模式更关注创建过程及细节。
基础术语
构建层
定义与作用
构建层是指 负责对象创建过程部分 的代码。
它定义了创建对象的步骤和方法,但不直接指定对象的具体表示形式。
构建层所拥有的角色
- 抽象构建者(Abstract Builder) :定义创建对象各个部件的接口。
- 具体构建者(Concrete Builder) :实现抽象构建者接口,逐步构建复杂对象的各个部件。
- 指挥者(Director) :使用构建者来创建对象,通常不依赖于具体构建者的实现,而是通过抽象构建者接口与构建者交互。
表示层
表示层是指对象的最终表示形式或结构。它定义了对象的内部状态和行为,但不直接参与对象的创建过程。表示层通常是一个独立的类,用于存储对象的属性和方法。
优点
- 分离构建过程与表示:将复杂的构建过程与最终的表示分离,使得可以使用不同的构建过程形成不同的最终表示。
- 逐步构建对象:允许逐步构建复杂对象,便于添加新的构建步骤。
- 代码复用:通过构建器类复用构建逻辑,减少重复代码。
- 灵活性:可以轻松地创建不同的对象表示,只需实现不同的构建器类。
缺点
- 增加代码复杂度:引入了额外的类,使得代码结构变得更加复杂。
- 可能产生过多的类:如果需要创建多种不同的对象表示,可能会产生过多的构建器类。
定义
将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示。
可以用不同组合或顺序建造出不同意义的对象,通常使用者并不需要知道建造的细节,通常使用链式调用 来进行建造过程,最后调用build
方法来生成最终对象。
应用场景
- 构建复杂的对象或界面组件
- 在需要分步骤创建对象时。
- 当需要为同一对象创建多种不同的表示时。
如何实现
- 实现表示层 类:主要用于描述最终产物的各种行为。
- 构建抽象建造者:主要用于确定构建功能模块的类型,并且创建表示层类的实例。
通常用一个有方法及属性但无具体实现的父类来表示。在ts可以使用接口类来代替父类。
对于一些与建造无关的方法可以将实现放置在父类,剩余的应该下放到子类实现。
会在构造函数中进行表示层类的实例的创建及存储。
- 构建具体建造者:抽象建造者的子类,相当于对抽象建造者描述的创建过程中各个功能模块进行具体实现。
每个功能模块应该返回 this ,方便后续链式调用
- 构建指挥者:主要集成了进行各种类型的对象构建的方法。
该步骤可以省略,直接合并至步骤 5
- 客户端使用:用于构建整体对象并使用,完成业务需求的实现
示例
动态表单生成器
需求说明
构建一个用户注册表单,包含基础信息、地址信息、偏好设置等模块,且不同场景下模块组合可能变化。
构建步骤
- 产出表示层类:表单配置对象,用于进行表单的各种行为的承载
typescript
class FormConfig {
constructor() {
this.fields = [];
}
addField(type, label, required = false) {
this.fields.push({ type, label, required });
}
render() {
return this.fields.map(field => <>表单项</>);
}
}
- 构建抽象建造者
javascript
class FormBuilder {
constructor() {
this.form = new FormConfig();
}
buildBasicInfo() {}
buildAddress() {}
buildPreferences() {}
getForm() {
return this.form;
}
}
- 构建具体建造者
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;
}
}
- 创建指挥者
kotlin
class FormDirector {
constructor(builder) {
this.builder = builder;
}
buildFullForm() {
return this.builder
.buildBasicInfo()
.buildAddress()
.buildPreferences()
.getForm();
}
buildMinimalForm() {
return this.builder
.buildBasicInfo()
.getForm();
}
}
- 客户端使用
ini
// 创建建造者
const builder = new RegistrationFormBuilder();
// 方式1:直接使用建造者(灵活自定步骤)
const customForm = builder
.buildBasicInfo()
.buildPreferences()
.getForm();
// 方式2:通过指挥者(标准化流程)
const director = new FormDirector(builder);
const fullForm = director.buildFullForm();