设计模式 - 建造者模式

111 阅读5分钟

设计模式 - 建造者模式

一、引入

当我们需要创建一个对象,这个对象拥有多个属性,而且这些属性之间可能还有一些复杂的关联关系时,直接创建对象可能会很繁琐,容易出错。

建造者模式就是帮助我们更方便地创建这种复杂对象的一种设计模式。

举个例子,比如要创建一辆汽车,它有很多属性:轮子的数量、引擎的功率、颜色等等。如果直接在代码里一行一行地去设置这些属性,会显得很繁琐。而建造者模式可以让我们通过一种更加友好的方式来创建汽车:

  1. 我们先找到一个汽车的“建造者”;
  2. 然后告诉建造者我们想要一辆红色、四轮驱动、200马力的汽车;
  3. 建造者根据我们的要求,一步一步地帮我们创建这辆汽车;
  4. 最后,我们拿到了我们想要的汽车。

这样,我们就通过建造者模式,以一种清晰、简单的方式创建了一辆复杂的汽车。

总的来说,建造者模式可以帮助我们创建那些拥有许多属性,且属性之间可能还有一些复杂关联的对象,让创建过程更加清晰、灵活。

二、概念

建造者模式(Builder Pattern)是一种创建型设计模式,它可以将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

三、基本结构

  1. 产品类(Product):定义了需要构建的复杂对象。
  2. 抽象建造者(Builder):定义了构建复杂对象的接口,包括了创建各个部件和最终组装的方法。
  3. 具体建造者(Concrete Builder):实现了抽象建造者接口,负责具体的构建过程。
  4. 指挥者(Director):负责使用具体建造者来构建复杂对象,也可以通过它来控制构建过程的顺序。

四、示例代码

/**
 * 产品类 : 定义了需要构建的复杂对象。
 */
public class Computer {
    private String cpu;
    private String memory;
    private String storage;

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

    public void setMemory(String memory) {
        this.memory = memory;
    }

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

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", storage='" + storage + '\'' +
                '}';
    }
}
/**
 * 抽象建造者 : 定义了构建复杂对象的接口,包括了创建各个部件和最终组装的方法。
 */
public interface ComputerBuilder {
    void buildCpu();

    void buildMemory();

    void buildStorage();

    Computer getResult();
}
/**
 * 具体建造者 : 实现了抽象建造者接口,负责具体的构建过程。
 *
 * @author zhangfan
 */
public class HighEndComputerBuilder implements ComputerBuilder {
    private Computer computer;

    public HighEndComputerBuilder() {
        this.computer = new Computer();
    }

    @Override
    public void buildCpu() {
        computer.setCpu("高配CPU");
    }

    @Override
    public void buildMemory() {
        computer.setMemory("Memory");
    }

    @Override
    public void buildStorage() {
        computer.setStorage("Storage");
    }

    @Override
    public Computer getResult() {
        return computer;
    }
}
/**
 * 指挥者 : 负责使用具体建造者来构建复杂对象,也可以通过它来控制构建过程的顺序。
 */
public class Director {
    private ComputerBuilder builder;

    public Director(ComputerBuilder builder) {
        this.builder = builder;
    }

    public Computer computer() {
        builder.buildCpu();
        builder.buildMemory();
        builder.buildStorage();
        return builder.getResult();
    }
}
/**
* 客户端
*/
public class Client {
    public static void main(String[] args) {
        HighEndComputerBuilder highEndComputerBuilder = new HighEndComputerBuilder();
        Director director = new Director(highEndComputerBuilder);
        Computer computer = director.computer();
        System.out.println(computer);
    }
}

五、用途

  1. 构建复杂对象:当一个对象的构建过程比较复杂,需要设置多个属性或者进行一系列的步骤,使用建造者模式可以将构建过程清晰地分离出来,使得代码更加可维护。
  2. 避免重叠构造器:在类的构造器中,如果有多个属性需要设置,往往会出现多个构造器的重叠,而使用建造者模式可以避免这种情况。
  3. 提高代码可读性:通过链式调用或者一步一步地设置属性,可以使代码更加清晰,易于阅读和理解。
  4. 灵活性和可扩展性:可以根据需要随时新增或修改建造者中的设置方法,而不会影响到客户端代码。
  5. 保护对象的一致性:在对象构建过程中,可以通过建造者来保证对象的一致性,避免了不完整或者不一致的对象被创建。

六、总结

优点:

  1. 封装性好:建造者模式将对象的创建过程封装在一个独立的建造者类中,使得客户端无需了解具体的构建过程,只需要知道如何使用建造者即可。
  2. 灵活性高:可以根据需要随时新增或修改建造者中的设置方法,而不会影响到客户端代码。
  3. 保护对象的一致性:在对象构建过程中,可以通过建造者来保证对象的一致性,避免了不完整或者不一致的对象被创建。
  4. 简化客户端代码:通过链式调用或者一步一步地设置属性,可以使客户端代码更加清晰、简洁。
  5. 可读性高:通过链式调用或者一步一步地设置属性,使得代码更加易于阅读和理解。

缺点:

  1. 增加了代码量:引入了建造者模式会增加额外的类和接口,相对于直接创建对象的方式,会增加一些代码量。
  2. 创建对象相对慢:相对于直接创建对象,使用建造者模式会略显繁琐,可能会稍微增加对象的创建时间。
  3. 不适用于对象属性较少的情况:如果一个对象的属性很少,使用建造者模式反而会显得繁琐,直接创建对象可能更加简单。

总的来说,建造者模式在需要创建复杂对象,且对象的构建过程较为繁琐或者需要保证对象的一致性时,是一种非常有效的设计模式。但在对象的属性较少或者构建过程简单的情况下,可能会显得过于繁琐。因此,在使用建造者模式时,需要根据具体情况进行权衡和选择。