在软件开发中,存在大量复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。
由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
建造者模式包含如下角色:
Builder:抽象建造者ConcreteBuilder:具体建造者Director:指挥者Product:产品电脑是每个程序员的标配,主要配件有:CPU、主板、内存、显卡、电源。当前主要有两大平台:AMD 和 Intel,但是两个平台的一些零件是不一样的。所以肥宅在组装两个平台时选择的配件也是不一样的。
产品(电脑):
public class Computer { /** * cpu */ private String cpu; /** * 主板 */ private String motherboar; /** * 内存 */ private String ram; /** * 显卡 */ private String graphicsCard; /** * 电源 */ private String power; //setter and getter // toString }抽象工厂:
abstract class AbstractComputerBuilder { /** * 选择CPU */ abstract void buildCPU(); /** * 选择主板 */ abstract void buildMotherboar(); /** * 选择内存 */ abstract void buildRam(); /** * 选择显卡 */ abstract void buildGraphicsCard(); /** * 选择电源 */ abstract void buildPower(); /** * 获取电脑 */ abstract Computer getComputer(); }具体建造者:
// AMD电脑 建造者 public class AmdComputerBuilder extends AbstractComputerBuilder { private Computer computer = new Computer(); @Override void buildCPU() { computer.setCpu("2700x"); } @Override void buildMotherboar() { computer.setMotherboar("华硕 ROG X470"); } @Override void buildRam() { computer.setRam("芝奇 DDR4 8G"); } @Override void buildGraphicsCard() { computer.setGraphicsCard("vega 56"); } @Override void buildPower() { computer.setPower("EVGA 750W"); } @Override Computer getComputer() { return computer; } } // Intel 电脑建造者 public class IntelComputerBuilder extends AbstractComputerBuilder { private Computer computer = new Computer(); @Override void buildCPU() { computer.setCpu("i7 8700"); } @Override void buildMotherboar() { computer.setMotherboar("微星 Z370"); } @Override void buildRam() { computer.setRam("金士顿 DDR4 8G"); } @Override void buildGraphicsCard() { computer.setGraphicsCard("GTX 1080Ti"); } @Override void buildPower() { computer.setPower("海韵 750W"); } @Override Computer getComputer() { return computer; } }指挥者:
public class ComputerDirector { public void construct(AbstractComputerBuilder builder) { builder.buildCPU(); builder.buildMotherboar(); builder.buildRam(); builder.buildGraphicsCard(); builder.buildPower(); } }测试:
public class Fz { @Test public void build() { ComputerDirector director = new ComputerDirector(); AmdComputerBuilder amdComputerBuilder = new AmdComputerBuilder(); director.construct(amdComputerBuilder); Computer amdComputer = amdComputerBuilder.getComputer(); System.out.println("选择AMD平台配件:" + amdComputer); IntelComputerBuilder intelComputerBuilder = new IntelComputerBuilder(); director.construct(intelComputerBuilder); Computer intelComputer = intelComputerBuilder.getComputer(); System.out.println("选择Intel平台配件:" + intelComputer); } }在以下情况下可以使用建造者模式:
需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。需要生成的产品对象的属性相互依赖,需要指定其生成顺序。对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。建造者模式与工厂模式类似,适用的场景也很相似。建造者模式仅仅只比工厂模式多了一个”指挥者”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。
建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。建造者模式更加关注与零件装配的顺序。
一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。