概念
软件开发过程中,复杂对象的创建步骤繁杂,这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。
复杂对象比如电脑、汽车、飞机、手机、冰箱…
这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,被称为建造者模式
建造者模式又叫生成器模式,是一种对象构建模式。
模拟场景
组装台式电脑,不同的人选择的配置和价位都不同,而且组装电脑需要的零件很多过程十分复杂。
用代码实现不同用户组装不同价位和配置的电脑
传统实现方式
根据上述场景,主要有以下几个类
AbstractComputer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public abstract class AbstractComputer { public abstract void cpu(); public abstract void ram(); public abstract void disk(); public abstract void graphics(); public abstract void power();
public void build(){ this.cpu(); this.ram(); this.disk(); this.graphics(); this.power(); } }
|
普通配置的电脑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class ComputerType1 extends AbstractComputer implements Serializable {
@Override public void cpu() { System.out.println("安装普通cpu"); }
@Override public void ram() { System.out.println("安装8g内存"); }
@Override public void disk() { System.out.println("安装500g机械硬盘"); }
@Override public void graphics() { System.out.println("安装低配显卡"); }
@Override public void power() { System.out.println("安装普通电源"); } }
|
客户类需要该配置电脑时进行构建
1 2 3 4 5 6
| public class Client { public static void main(String[] args) { ComputerType1 computerType1 = new ComputerType1(); computerType1.build(); } }
|
传统方式来实现电脑的组装流程是比较好理解的,但是电脑作为产品,组装过程与产品并没有完全解耦。
在设计模式中,有一种专门用于将产品与产品创建过程分析的方式,也叫做建造者模式
建造者模式
又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
他具有四个角色,分别为:
- Product(产品角色): 一个具体的产品对象。
- Builder(抽象建造者): 创建一个Product对象的各个部件指定的 接口/抽象类。
- ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。
- Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。
- 它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
模拟场景
电脑城买组装台式机。
从选机到下单到装机到提货流程繁多步骤复杂,
实际的流程是客户提出机器需求,装机店老板给出配置A和B两个套餐和价位,客户下单,老板根据配置单A/B指挥装机员A/B进行装机,装机员装好机器之后,由装机店老板转交客户
根据场景分析可得如下几个角色:
- 电脑:具体产品
- 装机店:抽象建造者
- 装机员A、B:具体建造者
- 装机店老板:指挥者
代码实现
产品角色Computer定义如下
1 2 3 4 5 6 7 8 9 10
| public class Computer { private String cpu; private String ram; private String disk; private String graphics; private String power; }
|
抽象建造者,定义所有建造者的基础方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public abstract class ComputerBuilder { Computer computer = new Computer(); public abstract void cpu(); public abstract void ram(); public abstract void disk(); public abstract void graphics(); public abstract void power();
public Computer build(){ this.cpu(); this.ram(); this.disk(); this.graphics(); this.power(); return computer; } }
|
具体的建造者角色,装机员A、B,此处以A为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ComputerInstallerA extends ComputerBuilder {
@Override public void cpu() {computer.setCpu("普通cpu");}
@Override public void ram() {computer.setRam("4G内存");}
@Override public void disk() {computer.setDisk("500G机械硬盘");}
@Override public void graphics() {computer.setGraphics("集成显卡");}
@Override public void power() {computer.setPower("普通电源");} }
|
指挥者角色,装机店老板,指挥装机员进行某一配置的装机
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class StoreBoss { ComputerBuilder builder = null;
public StoreBoss setBuilder(ComputerBuilder builder) { this.builder = builder; return this; }
public void builder(){ Computer computer = builder.build(); System.out.println(computer.toString()); } }
|
以上便是建造者模式的基础角色,编写客户类进行测试
1 2 3 4 5 6 7 8 9 10 11
| public class Client { public static void main(String[] args) { StoreBoss boss = new StoreBoss(); System.out.println("客户A的电脑配置:"); boss.setBuilder(new ComputerInstallerA()).builder(); System.out.println("客户B的电脑配置:"); boss.setBuilder(new ComputerInstallerB()).builder(); } }
|
客户只需要联系装机店老板,并告诉他自己的需求,即可进行按需装机
执行结果如下:
1 2 3 4
| 客户A的电脑配置: Computer{cpu='普通cpu', ram='4G内存', disk='500G机械硬盘', graphics='集成显卡', power='普通电源'} 客户B的电脑配置: Computer{cpu='高端cpu', ram='16G内存', disk='500G固态硬盘', graphics='GTX2080Ti显卡', power='金标550W电源'}
|
建造者模式与抽象工厂模式的比较
与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族 。
在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象
,返回一个完整的对象 。
如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车