建造者设计模式(Builder Pattern)是一种创建型设计模式,它专注于逐步构建复杂对象。它将对象的构建过程与其表示分离,允许相同的构建过程创建不同的表示形式。该模式的目标是简化对象的构建过程,并提供灵活性和可扩展性。
Builder设计模式的核心思想是将对象的构建过程从其实际表示中解耦。通常情况下,一个对象的构建过程是复杂且多步骤的,使用Builder模式可以将这些步骤分解为独立的方法,从而使得构建过程更加灵活和可控。
Builder设计模式包含以下几个主要组成部分:
Builder设计模式的基本流程如下:
下列是一个简单的建造者设计模式的例子,这段代码演示了如何使用建造者设计模式创建一个电脑对象。
首先,我们定义了一个Computer类,它具有一些属性(processor、memory、hardDisk、monitor)以及对应的设置方法。
然后,我们定义了一个ComputerBuilder接口,其中包含了构建电脑对象所需的方法(buildProcessor、buildMemory、buildHardDisk、buildMonitor)以及获取构建完成的电脑对象的方法getComputer()。
接着,我们实现了一个BasicComputerBuilder类,它是ComputerBuilder接口的具体实现。在BasicComputerBuilder类中,我们实例化了一个Computer对象,并实现了构建电脑各个部件的方法。
之后,我们创建了一个ComputerDirector类,它负责指导建造过程。通过调用ComputerBuilder的方法,按照一定的顺序构建电脑对象,并返回构建完成的对象。
最后,在Main类中,我们创建了一个BasicComputerBuilder对象作为建造者,创建了一个ComputerDirector对象作为指导者,然后通过指导者来构建电脑对象。最后,我们输出了构建完成的电脑对象的各个属性。
class Computer {
private String processor;
private String memory;
private String hardDisk;
private String monitor;
public void setProcessor(String processor) {
this.processor = processor;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void setMonitor(String monitor) {
this.monitor = monitor;
}
// 省略其他方法和属性的访问器
}
interface ComputerBuilder {
void buildProcessor();
void buildMemory();
void buildHardDisk();
void buildMonitor();
Computer getComputer();
}
class BasicComputerBuilder implements ComputerBuilder {
private Computer computer;
public BasicComputerBuilder() {
this.computer = new Computer();
}
public void buildProcessor() {
computer.setProcessor("Basic Processor");
}
public void buildMemory() {
computer.setMemory("4GB");
}
public void buildHardDisk() {
computer.setHardDisk("500GB");
}
public void buildMonitor() {
computer.setMonitor("15-inch");
}
public Computer getComputer() {
return computer;
}
}
class ComputerDirector {
public Computer buildComputer(ComputerBuilder builder) {
builder.buildProcessor();
builder.buildMemory();
builder.buildHardDisk();
builder.buildMonitor();
return builder.getComputer();
}
}
public class Main {
public static void main(String[] args) {
ComputerBuilder builder = new BasicComputerBuilder();
ComputerDirector director = new ComputerDirector();
Computer computer = director.buildComputer(builder);
System.out.println("Processor: " + computer.getProcessor());
System.out.println("Memory: " + computer.getMemory());
System.out.println("Hard Disk: " + computer.getHardDisk());
System.out.println("Monitor: " + computer.getMonitor());
}
}
在这个示例中,我们通过建造者模式逐步构建了一个电脑对象。指导者类控制了建造过程,而具体的建造者类负责实际构建对象。最终,我们可以获取到一个完整的电脑对象,并对其进行进一步操作。
Builder设计模式适用于以下情况:
在这个示例中,我们使用建造者设计模式创建了一个名为 ImmutablePerson
的不可变对象类。
在 ImmutablePerson
类中,属性 name
、age
和 address
被声明为 final
,并且没有提供任何修改它们的方法。这样可以确保这些属性在对象创建后不可变。
通过私有的构造方法 ImmutablePerson(Builder builder)
,我们将属性的值从 Builder
对象传递给了 ImmutablePerson
对象,并在构造方法内进行了赋值操作。这样,我们可以在构造对象时保证对象的属性值一致和不可变。
Builder
类是一个嵌套类,它提供了链式调用的方法来设置 ImmutablePerson
的属性值。每个方法都返回 Builder
对象本身,以便可以连续调用多个方法。最后,通过调用 build()
方法,我们可以创建并返回一个不可变的 ImmutablePerson
对象。
使用该示例,我们可以这样创建一个不可变的 ImmutablePerson
对象:
public final class ImmutablePerson {
private final String name;
private final int age;
private final String address;
private ImmutablePerson(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
public static class Builder {
private String name;
private int age;
private String address;
public Builder() {
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public ImmutablePerson build() {
return new ImmutablePerson(this);
}
}
public static void main(String[] args) {
// Usage example:
ImmutablePerson person = new ImmutablePerson.Builder()
.setName("John")
.setAge(30)
.setAddress("123 Street")
.build();
}
}
在这个示例中,我们通过链式调用 Builder
的方法设置属性的值,并最后调用 build()
方法来创建 ImmutablePerson
对象。一旦对象创建完成,它的属性就是不可变的,无法再修改。
这种方式提供了不可变对象的安全性和线程安全性,因为对象的状态无法在创建后被修改。不可变对象还可以更容易地进行缓存、共享和使用。
lombok例子:
在lombok中,我们使用@Builder
注解会自动生成一个建造者模式的构建者类。下面是一个使用Lombok的@Builder
注解的示例代码:
非常抱歉前面的回答中有些遗漏,确实是多了一些代码。以下是编译前和编译后的代码:
编译前的代码:
@Builder
@Getter
@ToString
public class User {
private String name;
private Integer age;
private String bobby;
public static void main(String[] args) {
User.UserBuilder builder = new UserBuilder();
User user = builder.name("jack").age(18).bobby("rap").build();
System.out.println("user = " + user);
}
}
编译后的代码:
public class User {
private String name;
private Integer age;
private String bobby;
public static void main(String[] args) {
UserBuilder builder = new UserBuilder();
User user = builder.name("jack").age(18).bobby("rap").build();
System.out.println("user = " + user);
}
User(String name, Integer age, String bobby) {
this.name = name;
this.age = age;
this.bobby = bobby;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
public String getBobby() {
return this.bobby;
}
public String toString() {
return "User(name=" + this.getName() + ", age=" + this.getAge() + ", bobby=" + this.getBobby() + ")";
}
public static class UserBuilder {
private String name;
private Integer age;
private String bobby;
UserBuilder() {
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(Integer age) {
this.age = age;
return this;
}
public UserBuilder bobby(String bobby) {
this.bobby = bobby;
return this;
}
public User build() {
return new User(this.name, this.age, this.bobby);
}
public String toString() {
return "User.UserBuilder(name=" + this.name + ", age=" + this.age + ", bobby=" + this.bobby + ")";
}
}
}
请注意,编译后的代码中添加了一些内容,其中包括:
User
类中,添加了私有构造函数以及对应的属性赋值操作。User
类中,添加了getter方法和toString()
方法的具体实现。User
类中,添加了静态的builder()
方法,用于创建UserBuilder
对象。UserBuilder
类中,添加了构造函数、链式调用方法以及build()
方法的具体实现。这些额外的代码是Lombok库根据注解自动生成的,它们帮助简化了建造者模式的使用,减少了手动编写重复代码的工作量。这样,您可以更方便地创建和操作User
对象。
Builder设计模式的优点包括:
然而,Builder设计模式也存在一些缺点:
总的来说,Builder设计模式在构建复杂对象时非常有用,并提供了灵活性和可扩展性。但在简单情况下,使用该模式可能会带来一定的开销。
建造者设计模式和工厂设计模式是两种常见的创建型设计模式,它们都用于创建对象,但在目的和使用方式上存在一些区别。
现在,让我们结合生活中的一个例子来说明这两种设计模式的区别。
总结一下,工厂设计模式适用于创建不同类型的对象,而建造者设计模式适用于逐步构建复杂对象。工厂模式隐藏了对象的创建细节,而建造者模式允许按照特定的步骤或顺序构建对象,并允许在构建过程中进行配置和定制。