设计模式之建造者模式

发布于:2024-04-24 ⋅ 阅读:(24) ⋅ 点赞:(0)

1、简单介绍:

建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这种模式适用于需要分步骤创建复杂对象、构造过程可能需要改变、或者需要隐藏复杂对象的具体构建过程的场景。

2、主要角色

  • Product(产品):表示需要构建的复杂对象。
  • Builder(抽象建造者):定义创建产品对象的各个部分(部件)的接口,并声明一个返回产品对象的方法。
  • ConcreteBuilder(具体建造者):实现抽象建造者的接口,具体定义创建产品对象各部分的方法,并提供一个方法返回创建完成的产品对象。
  • Director(指挥者):负责安排复杂对象的构建顺序,它只与抽象建造者接口交互,不关心具体的建造细节。指挥者可以构造一个指导创建过程的算法,统一构造过程。

3、Java代码示例:

假设我们有一个复杂的Computer类,包含多个组成部分(CPU、RAM、HardDrive等),我们使用建造者模式来构建它:

// Product(产品)
public class Computer {
    private String cpu;
    private int ram;
    private String hardDrive;

    public Computer(String cpu, int ram, String hardDrive) {
        this.cpu = cpu;
        this.ram = ram;
        this.hardDrive = hardDrive;
    }

    public String getCpu() {
        return cpu;
    }

    public int getRam() {
        return ram;
    }

    public String getHardDrive() {
        return hardDrive;
    }

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

// Builder(抽象建造者)
public abstract class ComputerBuilder {
    protected Computer computer;

    public ComputerBuilder() {
        computer = new Computer("", 0, "");
    }

    public abstract void buildCpu(String cpu);
    public abstract void buildRam(int ram);
    public abstract void buildHardDrive(String hardDrive);

    public Computer getComputer() {
        return computer;
    }
}

// ConcreteBuilder(具体建造者)
public class DesktopComputerBuilder extends ComputerBuilder {
    @Override
    public void buildCpu(String cpu) {
        computer.setCpu(cpu);
    }

    @Override
    public void buildRam(int ram) {
        computer.setRam(ram);
    }

    @Override
    public void buildHardDrive(String hardDrive) {
        computer.setHardDrive(hardDrive);
    }
}

// Director(指挥者)
public class ComputerDirector {
    public Computer constructDesktopComputer(String cpu, int ram, String hardDrive) {
        DesktopComputerBuilder builder = new DesktopComputerBuilder();
        builder.buildCpu(cpu);
        builder.buildRam(ram);
        builder.buildHardDrive(hardDrive);
        return builder.getComputer();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ComputerDirector director = new ComputerDirector();
        Computer desktop = director.constructDesktopComputer("Intel Core i7", 16, "SSD 512GB");
        System.out.println(desktop);
    }
}

4、使用过程中可能遇到的问题:

过度设计:如果对象并不复杂,或者创建过程不需要灵活变化,使用建造者模式可能会显得过度设计。在这种情况下,直接使用构造函数或工厂方法创建对象可能更为合适。

建造者类膨胀:随着产品复杂性的增加,建造者类可能会包含大量方法,变得难以理解和维护。

与模板方法模式混淆:建造者模式和模板方法模式在结构上有些相似,可能会导致混淆。模板方法模式主要用于算法骨架的固定与实现步骤的可变,而建造者模式关注的是复杂对象的构建过程。

不符合单一职责原则:有时建造者可能同时负责创建对象和管理对象的生命周期,这违反了单一职责原则。

测试困难:由于建造者模式涉及多个类和复杂的交互,可能使得单元测试变得困难。

5、可能遇到的问题的解决方案:

过度设计解决方案:评估对象的复杂度和构建过程的需求,确保建造者模式是必要的。对于简单对象,选择更轻量级的创建方式。

建造者类膨胀解决方案:可以考虑将建造者类拆分为多个子建造者,每个子建造者负责构建产品的一部分。这样可以降低单个建造者的复杂度,同时保持构建过程的灵活性。

与模板方法模式混淆解决方案:明确区分两种模式的应用场景和目的,根据实际需求选择合适的模式。

不符合单一职责原则解决方案:确保建造者仅负责对象的构建,对象的管理和生命周期应由其他组件(如工厂、容器等)负责。可以结合其他设计模式(如工厂模式、服务定位器模式等)来分离这些职责。

测试困难解决方案:为建造者类和产品类编写详细的单元测试,确保每个部分的行为符合预期。使用依赖注入或模拟对象技术来隔离测试,便于测试不同组合和配置。

注意

        建造者模式在构建复杂对象时能够提供清晰、灵活的创建过程,但需注意避免过度设计、类膨胀等问题,并确保与相关设计原则和模式正确结合,以提升代码的可读性、可维护性和可测试性。