Builder Pattern
用建造者模式分步构建复杂对象
问题
什么是建造者模式?如何在 JavaScript 中实现?
解答
建造者模式将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。适用于需要创建包含多个可选参数的对象。
基础实现
class UserBuilder {
constructor(name) {
this.name = name;
}
setAge(age) {
this.age = age;
return this; // 返回 this 支持链式调用
}
setEmail(email) {
this.email = email;
return this;
}
setAddress(address) {
this.address = address;
return this;
}
build() {
return {
name: this.name,
age: this.age,
email: this.email,
address: this.address,
};
}
}
// 使用
const user = new UserBuilder('张三')
.setAge(25)
.setEmail('zhangsan@example.com')
.setAddress('北京')
.build();
console.log(user);
// { name: '张三', age: 25, email: 'zhangsan@example.com', address: '北京' }
带 Director 的完整实现
// 产品类
class Computer {
constructor() {
this.parts = {};
}
setPart(name, value) {
this.parts[name] = value;
}
show() {
console.log('电脑配置:', this.parts);
}
}
// 抽象建造者
class ComputerBuilder {
constructor() {
this.computer = new Computer();
}
buildCPU() {}
buildMemory() {}
buildStorage() {}
getResult() {
return this.computer;
}
}
// 具体建造者 - 游戏电脑
class GamingComputerBuilder extends ComputerBuilder {
buildCPU() {
this.computer.setPart('CPU', 'Intel i9');
return this;
}
buildMemory() {
this.computer.setPart('Memory', '32GB DDR5');
return this;
}
buildStorage() {
this.computer.setPart('Storage', '2TB SSD');
return this;
}
}
// 具体建造者 - 办公电脑
class OfficeComputerBuilder extends ComputerBuilder {
buildCPU() {
this.computer.setPart('CPU', 'Intel i5');
return this;
}
buildMemory() {
this.computer.setPart('Memory', '16GB DDR4');
return this;
}
buildStorage() {
this.computer.setPart('Storage', '512GB SSD');
return this;
}
}
// 指挥者 - 控制构建流程
class Director {
construct(builder) {
return builder.buildCPU().buildMemory().buildStorage().getResult();
}
}
// 使用
const director = new Director();
const gamingPC = director.construct(new GamingComputerBuilder());
gamingPC.show();
// 电脑配置: { CPU: 'Intel i9', Memory: '32GB DDR5', Storage: '2TB SSD' }
const officePC = director.construct(new OfficeComputerBuilder());
officePC.show();
// 电脑配置: { CPU: 'Intel i5', Memory: '16GB DDR4', Storage: '512GB SSD' }
实际应用:请求构建器
class RequestBuilder {
constructor(url) {
this.url = url;
this.method = 'GET';
this.headers = {};
this.body = null;
this.timeout = 5000;
}
setMethod(method) {
this.method = method;
return this;
}
setHeader(key, value) {
this.headers[key] = value;
return this;
}
setBody(body) {
this.body = JSON.stringify(body);
return this;
}
setTimeout(timeout) {
this.timeout = timeout;
return this;
}
async send() {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
try {
const response = await fetch(this.url, {
method: this.method,
headers: this.headers,
body: this.body,
signal: controller.signal,
});
clearTimeout(timeoutId);
return response.json();
} catch (error) {
clearTimeout(timeoutId);
throw error;
}
}
}
// 使用
const response = await new RequestBuilder('/api/users')
.setMethod('POST')
.setHeader('Content-Type', 'application/json')
.setHeader('Authorization', 'Bearer token')
.setBody({ name: '张三', age: 25 })
.setTimeout(10000)
.send();
关键点
- 链式调用:每个设置方法返回
this,支持流畅的 API 设计 - 分离构建与表示:相同的构建过程可以创建不同的对象
- 可选参数处理:避免构造函数参数过多的问题
- Director 可选:简单场景可省略,复杂场景用于封装固定构建流程
- 适用场景:创建复杂对象、需要多步骤初始化、参数组合多样
目录