设计模式(4)-建造者模式

概念

软件开发过程中,复杂对象的创建步骤繁杂,这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。

复杂对象比如电脑、汽车、飞机、手机、冰箱…

这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,被称为建造者模式

建造者模式又叫生成器模式,是一种对象构建模式。

模拟场景

组装台式电脑,不同的人选择的配置和价位都不同,而且组装电脑需要的零件很多过程十分复杂。

用代码实现不同用户组装不同价位和配置的电脑

传统实现方式

根据上述场景,主要有以下几个类

  • 抽象电脑类
  • 具体电脑类A、B
  • 客户类

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 {
/**安装cpu*/
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;

//get、set、toString省略
}

抽象建造者,定义所有建造者的基础方法

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();
/**安装cpu*/
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();
//客户A需要一台价格便宜的电脑
System.out.println("客户A的电脑配置:");
boss.setBuilder(new ComputerInstallerA()).builder();
//客户B需要一台高配高性能电脑
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电源'}

建造者模式与抽象工厂模式的比较

与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族 。
在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象 。

如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

---------- 😏本文结束  感谢您的阅读😏 ----------
评论