跳转至

Java 中的建造者模式

简介

在软件开发中,创建对象的过程有时会变得复杂,特别是当对象有许多属性,并且这些属性之间存在复杂的依赖关系时。建造者模式(Builder Pattern)作为一种创建型设计模式,提供了一种创建对象的优雅方式,它将对象的构建和表示分离,使得构建过程更加清晰、可维护和可扩展。本文将深入探讨 Java 中的建造者模式,包括其基础概念、使用方法、常见实践以及最佳实践。

目录

  1. 基础概念
  2. 使用方法
  3. 常见实践
  4. 最佳实践
  5. 小结
  6. 参考资料

基础概念

建造者模式主要包含以下几个角色: - 产品(Product):需要创建的复杂对象。 - 抽象建造者(Builder):定义创建产品各个部分的抽象方法。 - 具体建造者(ConcreteBuilder):实现抽象建造者的方法,负责具体的产品构建过程。 - 指挥者(Director):负责调用建造者的方法来构建产品,控制构建的顺序。

使用方法

代码示例

下面通过一个创建电脑对象的例子来展示建造者模式的使用。

产品类(Computer)

public class Computer {
    private String cpu;
    private String ram;
    private String storage;

    // 私有构造函数,防止外部直接实例化
    private Computer(ComputerBuilder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", storage='" + storage + '\'' +
                '}';
    }

    // 静态内部类,作为建造者
    public static class ComputerBuilder {
        private String cpu;
        private String ram;
        private String storage;

        public ComputerBuilder setCpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public ComputerBuilder setRam(String ram) {
            this.ram = ram;
            return this;
        }

        public ComputerBuilder setStorage(String storage) {
            this.storage = storage;
            return this;
        }

        public Computer build() {
            return new Computer(this);
        }
    }
}

测试代码

public class BuilderPatternDemo {
    public static void main(String[] args) {
        Computer computer = new Computer.ComputerBuilder()
              .setCpu("Intel Core i7")
              .setRam("16GB")
              .setStorage("512GB SSD")
              .build();
        System.out.println(computer);
    }
}

解析

在上述代码中: 1. Computer 类是产品类,它有 cpuramstorage 三个属性,并且构造函数是私有的,防止外部直接创建实例。 2. ComputerBuilderComputer 类的静态内部类,作为具体建造者。它提供了设置各个属性的方法,并且返回 this,以便链式调用。build 方法用于创建并返回最终的 Computer 对象。 3. 在 main 方法中,通过 Computer.ComputerBuilder 来创建 Computer 对象,代码简洁明了,易于理解和维护。

常见实践

省略指挥者角色

在很多实际应用中,指挥者角色可以省略。因为如果构建过程并不复杂,直接在客户端代码中调用建造者的方法来构建产品会更加简洁。就像上面的 Computer 例子,我们没有使用指挥者角色,而是在 main 方法中直接调用 ComputerBuilder 的方法来构建 Computer 对象。

与工厂模式结合

建造者模式可以和工厂模式结合使用。工厂模式负责创建对象,而建造者模式负责对象的复杂构建过程。例如,一个工厂方法可以返回一个建造者实例,然后客户端通过这个建造者来完成对象的构建。

public class ComputerFactory {
    public static Computer.ComputerBuilder getComputerBuilder() {
        return new Computer.ComputerBuilder();
    }
}

使用时:

public class BuilderAndFactoryDemo {
    public static void main(String[] args) {
        Computer computer = ComputerFactory.getComputerBuilder()
              .setCpu("AMD Ryzen 9")
              .setRam("32GB")
              .setStorage("1TB NVMe SSD")
              .build();
        System.out.println(computer);
    }
}

最佳实践

链式调用的一致性

在建造者类中,所有设置属性的方法都应该返回 this,以实现链式调用。这样可以使代码更加简洁和易读。

验证和错误处理

build 方法中,应该对构建的对象进行必要的验证。如果对象的某些属性不符合要求,应该抛出适当的异常,以便及时发现和处理问题。

public class ComputerBuilder {
    //...

    public Computer build() {
        if (cpu == null || ram == null || storage == null) {
            throw new IllegalArgumentException("CPU, RAM and storage are required");
        }
        return new Computer(this);
    }
}

不可变对象

如果产品对象不需要支持属性的修改,可以将其设计为不可变对象。在构造函数中设置所有属性后,不再提供修改属性的方法,这样可以提高对象的安全性和可维护性。

public class ImmutableComputer {
    private final String cpu;
    private final String ram;
    private final String storage;

    public ImmutableComputer(ImmutableComputerBuilder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
    }

    // getters only
    public String getCpu() {
        return cpu;
    }

    public String getRam() {
        return ram;
    }

    public String getStorage() {
        return storage;
    }

    // 静态内部类,作为建造者
    public static class ImmutableComputerBuilder {
        private String cpu;
        private String ram;
        private String storage;

        // 设置属性方法
        public ImmutableComputerBuilder setCpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public ImmutableComputerBuilder setRam(String ram) {
            this.ram = ram;
            return this;
        }

        public ImmutableComputerBuilder setStorage(String storage) {
            this.storage = storage;
            return this;
        }

        public ImmutableComputer build() {
            if (cpu == null || ram == null || storage == null) {
                throw new IllegalArgumentException("CPU, RAM and storage are required");
            }
            return new ImmutableComputer(this);
        }
    }
}

小结

建造者模式是 Java 中一种强大的设计模式,它通过将对象的构建和表示分离,使得创建复杂对象的过程更加清晰、可维护和可扩展。通过省略指挥者角色、与工厂模式结合等常见实践,以及遵循链式调用一致性、验证和错误处理、创建不可变对象等最佳实践,可以更好地运用建造者模式来提升代码的质量和可维护性。

参考资料