建造者模式是一种创建型设计模式,它允许你创建复杂对象的过程与其表示分离,从而使得同样的构建过程可以创建不同的表示。
该模式将对象的构建过程分解为一系列步骤,每个步骤都由一个独立的建造者对象负责完成。通过将这些步骤组合在一起,可以创建出不同的对象表示。
建造者模式可以帮助你在不同的场景下创建出复杂的对象,同时也可以使得代码更加灵活和易于维护。
建造者模式
在Java中,建造者模式可以通过以下步骤实现:
- 创建一个产品类,该类包含需要构建的属性和方法。
- 创建一个抽象建造者类,该类定义了构建产品所需的方法。
- 创建具体的建造者类,该类实现了抽象建造者类中定义的方法,用于构建产品。
- 创建一个指挥者类,该类负责调用具体建造者类中的方法来构建产品。
- 在客户端代码中,创建一个指挥者对象并将其传递给具体建造者类,然后调用指挥者对象的构建方法来构建产品。
以下是一个简单的Java代码示例,演示了如何使用建造者模式来构建一个电脑对象:
// 产品类
class Computer {
private String cpu;
private String memory;
private String hardDisk;
private String display;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void setDisplay(String display) {
this.display = display;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", hardDisk='" + hardDisk + '\'' +
", display='" + display + '\'' +
'}';
}
}
// 抽象建造者类
abstract class ComputerBuilder {
protected Computer computer;
public Computer getComputer() {
return computer;
}
public void createNewComputer() {
computer = new Computer();
}
public abstract void buildCpu();
public abstract void buildMemory();
public abstract void buildHardDisk();
public abstract void buildDisplay();
}
// 具体建造者类
class DesktopBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel Core i7");
}
@Override
public void buildMemory() {
computer.setMemory("16GB DDR4");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("1TB HDD");
}
@Override
public void buildDisplay() {
computer.setDisplay("24-inch LED");
}
}
// 指挥者类
class Director {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer getComputer() {
return computerBuilder.getComputer();
}
public void constructComputer() {
computerBuilder.createNewComputer();
computerBuilder.buildCpu();
computerBuilder.buildMemory();
computerBuilder.buildHardDisk();
computerBuilder.buildDisplay();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Director director = new Director();
ComputerBuilder desktopBuilder = new DesktopBuilder();
director.setComputerBuilder(desktopBuilder);
director.constructComputer();
Computer computer = director.getComputer();
System.out.println(computer);
}
}
在上面的示例中,我们创建了一个产品类Computer,它包含了需要构建的属性。
然后我们创建了一个抽象建造者类ComputerBuilder,它定义了构建产品所需的方法。
接着我们创建了一个具体建造者类DesktopBuilder,它实现了ComputerBuilder中定义的方法,用于构建电脑对象。
最后,我们创建了一个指挥者类Director,它负责调用具体建造者类中的方法来构建产品。
在客户端代码中,我们创建了一个指挥者对象并将其传递给具体建造者类,然后调用指挥者对象的构建方法来构建产品。
变形1: 静态内部类建造者模式
以上实现有个缺点是会创建多个建造者实例, 对此可以进一步优化, 将建造者类作为外部类的静态内部类, 也就成了静态内部类建造者模式,
例如:
public class Person {
private final String firstName;
private final String lastName;
private final int age;
private final String address;
private final String phone;
private Person(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.address = builder.address;
this.phone = builder.phone;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
public String getPhone() {
return phone;
}
public static class Builder {
private final String firstName;
private final String lastName;
private int age;
private String address;
private String phone;
//
public Builder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Person build() {
return new Person(this);
}
}
}
在这个示例中,我们定义了一个Person类,它有五个属性:firstName、lastName、age、address和phone。
我们使用静态内部类Builder来构建Person对象。
Builder类有与Person类相同的属性,但是它们都是可选的。我们可以使用Builder类的方法来设置这些属性,然后调用build()方法来创建Person对象。
在Person类的构造函数中,我们将Builder对象的属性复制到Person对象中。
使用静态内部类建造者模式的好处是,它可以使代码更加清晰和易于维护。它还可以避免在Person类中出现过多的构造函数和setter方法。
变形2: 线程安全的建造者模式
public class Person {
private final String firstName;
private final String lastName;
private final int age;
private final String address;
private final String phone;
private Person(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.address = builder.address;
this.phone = builder.phone;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
public String getPhone() {
return phone;
}
public static class Builder {
private String firstName;
private String lastName;
private int age;
private String address;
private String phone;
public Builder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public synchronized Builder age(int age) {
this.age = age;
return this;
}
public synchronized Builder address(String address) {
this.address = address;
return this;
}
public synchronized Builder phone(String phone) {
this.phone = phone;
return this;
}
public synchronized Person build() {
return new Person(this);
}
}
}
// 使用示例
Person person = new Person.Builder("John", "Doe")
.age(30)
.address("123 Main St")
.phone("555-555-1212")
.build();
上述代码中,我们在Builder类的方法上添加了synchronized关键字,以确保在多线程环境下创建Person对象时的线程安全性。
变形3: 建造者模式和单例模式结合
在某些情况下,我们需要创建一个复杂对象,并且这个对象只能有一个实例。这时,我们可以使用建造者模式来创建这个对象,同时使用单例模式来保证这个对象只有一个实例。
下面是一个示例代码,演示了如何使用建造者模式和单例模式的结合:
- 定义实体类,该类只能有一个实例。
public class ComplexObject {
private String part1;
private String part2;
private String part3;
public ComplexObject(String part1, String part2, String part3) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
}
}
- 定义一个建造者类,该类用于创建复杂对象。
public class Builder {
private String part1;
private String part2;
private String part3;
public Builder setPart1(String part1) {
this.part1 = part1;
return this;
}
public Builder setPart2(String part2) {
this.part2 = part2;
return this;
}
public Builder setPart3(String part3) {
this.part3 = part3;
return this;
}
public ComplexObject build() {
return new ComplexObject(part1, part2, part3);
}
}
- 定义一个单例类, 在单例类中使用建造者类创建复杂对象。
public class Singleton {
private volatile static Singleton instance;
private ComplexObject complexObject;
private Singleton() {
complexObject = new Builder()
.setPart1("part1")
.setPart2("part2")
.setPart3("part3")
.build();
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public ComplexObject getComplexObject() {
return complexObject;
}
}
这样,我们就实现了建造者模式和单例模式的结合。在这个例子中,我们使用单例模式保证了只有一个实例,使用建造者模式创建了一个复杂对象。同时,我们也可以通过单例类的方法获取这个复杂对象。
如果关于单例模式有疑问, 可查看我的另一篇博客java 单例模式 5种实现方式
网友评论