
介绍
作为开发人员,我们所有人都遇到过需要创建对象的情况。尝试为此对象设计通用类的问题是它可以采用多种形式。一个简单的例子:平台的 User 类。对于普通用户,我们可能只需要一个电子邮件和一个用户名。但是,对于平台管理员来说,可能需要电话号码等其他属性。我们还可以有一个高级用户,其中需要额外的字段,例如信用卡号等。
那么,我们如何才能以通用的方式进行呢?
面对这个问题,开发者社区商定了一个流行的创建模式:Builder设计模式。此模式涉及将复杂对象的构造与其表示分离,从而允许使用相同的构造过程创建多个对象变体。
此模式对于具有许多属性的对象特别有用,其中一些属性对于某些情况可能是可选的,但对于其他情况则不然,或者对于需要详细初始化过程的对象。它允许灵活、逐步创建对象,而不会使代码过于复杂或构造函数过于重载。
我们将涵盖的部分
- 什么是构建器模式?
- 什么时候应该使用它?
- 构建器使用的真实示例
- 为什么这个模式如此重要?
- 结论
## 什么是构建器模式?
构建器设计模式是一种创造性的设计模式,允许控制和灵活地构造复杂对象。构建器没有使用带有大量参数的构造函数,而是提供了一个平滑的接口来逐步创建对象。当对象有很多属性、特定的构建步骤或多种可能的配置时,它非常有用。
什么时候应该使用它?
构建器设计模式在以下情况下特别有用:
如果一个对象有很多属性,其中一些属性是可选的:回到我们在本文开头提出的问题,让我们考虑 User 类。根据我们描述的逻辑,如果我们实例化这个 User 类,我们可能会遇到不同的情况:对于普通用户,normalUser = new User("houda", "houda@gmail.com", null, null),对于管理员adminUser = new User("houda", "houda@gmail.com", "0657...", null),对于高级用户,premiumUser = new User("houda", "houda@gmail.com",无效的, “1234……”)。这会导致实例化中出现许多空值。
具有多步骤创建过程的对象:一个示例是 Order 类。第一步是下订单,然后准备,最后交付。准备订单可能需要多个步骤,为了确保正确的构建顺序,构建器设计模式非常有用。
支持同一对象的多种表示:例如,具有面料、颜色和品牌属性的 Clothing 类。服装可以是裤子、T 恤或其他类型。在这里,构建器模式有助于创建同一基类的不同表示。
构建器使用的真实示例
对于我们之前在本节中看到的每种情况,我们将看到构建器的实现
- 如果一个对象有很多属性,其中一些属性是可选的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | class User {
username: string;
email: string;
phoneNumber?: string;
creditCard?: string;
private constructor(builder: UserBuilder) {
this.username = builder.username;
this.email = builder.email;
this.phoneNumber = builder.phoneNumber;
this.creditCard = builder.creditCard;
}
public static get Builder() {
return new UserBuilder();
}
}
class UserBuilder {
username!: string;
email!: string;
phoneNumber?: string;
creditCard?: string;
public setUsername(username: string): UserBuilder {
this.username = username;
return this;
}
public setEmail(email: string): UserBuilder {
this.email = email;
return this;
}
public setPhoneNumber(phoneNumber: string): UserBuilder {
this.phoneNumber = phoneNumber;
return this;
}
public setCreditCard(creditCard: string): UserBuilder {
this.creditCard = creditCard;
return this;
}
public build(): User {
return new User(this);
}
}
const normalUser = User.Builder
.setUsername( "houda" )
.setEmail( "houda@gmail.com" )
.build();
const adminUser = User.Builder
.setUsername( "houda" )
.setEmail( "houda@gmail.com" )
.setPhoneNumber( "0657...." )
.build();
const premiumUser = User.Builder
.setUsername( "houda" )
.setEmail( "houda@gmail.com" )
.setCreditCard( "1234...." )
.build();
|
登录后复制
- 具有多步骤创建过程的对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | class Order {
private state: string;
private constructor(builder: OrderBuilder) {
this.state = builder.state;
}
public static get Builder() {
return new OrderBuilder();
}
public getState(): string {
return this.state;
}
}
class OrderBuilder {
state: string = "Placed" ;
public prepareOrder(): OrderBuilder {
if (this.state === "Placed" ) {
this.state = "Prepared" ;
}
return this;
}
public deliverOrder(): OrderBuilder {
if (this.state === "Prepared" ) {
this.state = "Delivered" ;
}
return this;
}
public build(): Order {
return new Order(this);
}
}
const completedOrder = Order.Builder
.prepareOrder()
.deliverOrder()
.build();
console.log(completedOrder.getState());
|
登录后复制
- 支持同一对象的多种表示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | class Clothing {
type: string;
fabric: string;
color: string;
brand: string;
private constructor(builder: ClothingBuilder) {
this.type = builder.type;
this.fabric = builder.fabric;
this.color = builder.color;
this.brand = builder.brand;
}
public static get Builder() {
return new ClothingBuilder();
}
}
class ClothingBuilder {
type!: string;
fabric!: string;
color!: string;
brand!: string;
public setType(type: string): ClothingBuilder {
this.type = type;
return this;
}
public setFabric(fabric: string): ClothingBuilder {
this.fabric = fabric;
return this;
}
public setColor(color: string): ClothingBuilder {
this.color = color;
return this;
}
public setBrand(brand: string): ClothingBuilder {
this.brand = brand;
return this;
}
public build(): Clothing {
return new Clothing(this);
}
}
const tShirt = Clothing.Builder
.setType( "T-Shirt" )
.setFabric( "Cotton" )
.setColor( "Blue" )
.setBrand( "BrandA" )
.build();
const pants = Clothing.Builder
.setType( "Pants" )
.setFabric( "Denim" )
.setColor( "Black" )
.setBrand( "BrandB" )
.build();
|
登录后复制
为什么这个模式如此重要?
构建器设计模式很重要,有几个关键原因,特别是在管理对象创建的复杂性时。这就是它如此有价值的原因:
- 处理复杂对象
当一个对象有很多属性,其中一些属性可能是可选的或需要按特定顺序设置时,构建器模式提供了一种清晰且结构化的方法来创建对象。
- 提高代码可读性和可维护性
通过将对象创建逻辑与对象本身分离,构建器模式使代码更具可读性且更易于维护。
- 减少构造函数重载
构建器模式不再需要具有不同参数组合的多个构造函数,而是消除了构造函数重载的需要。
- 明确分离关注点
构建器将对象的构造与其表示分离。这意味着您可以更改对象的构造方式而不影响其表示,反之亦然。
结论
构建器设计模式是开发人员处理复杂对象创建的必备工具。通过将构建过程分解为清晰、可管理的步骤,它提高了代码的可读性、可维护性和灵活性。无论您正在使用具有许多属性、需要多步骤构造还是需要支持多种配置的对象,构建器模式都提供了一个优雅的解决方案,可以防止构造函数过于复杂并减少错误。
博客涵盖:
- 什么是构建器模式?
- 什么时候应该使用它?
- 构建器使用的真实示例
- 为什么这个模式如此重要?
以上是掌握构建器设计模式:简化复杂对象的创建的详细内容。更多信息请关注PHP中文网其他相关文章!