惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
小众软件
小众软件
S
SegmentFault 最新的问题
GbyAI
GbyAI
量子位
爱范儿
爱范儿
L
LangChain Blog
Vercel News
Vercel News
A
About on SuperTechFans
腾讯CDC
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
V
Visual Studio Blog
美团技术团队
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium

Java技术经验分享

生产故障处理SOP分享 | Java技术经验分享 系统稳定性建设实践总结【转载】 | Java技术经验分享 valine访问leancloud国际版异常,评论失效修复 | Java技术经验分享 匆匆忙忙的2021 | Java技术经验分享 聊一下换工作 | Java技术经验分享 IoT系列(2):WIFI设备常见配网方案介绍 | Java技术经验分享 IoT系列(1):什么是物联网 | Java技术经验分享 Java8特性2 - StreamApi | Java技术经验分享 Java8特性1 - lambda表达式&函数式接口 | Java技术经验分享 设计模式(5)-适配器模式 | Java技术经验分享 设计模式(3)-原型模式与浅拷贝和深拷贝 | Java技术经验分享 设计模式(2)-工厂模式图文介绍 | Java技术经验分享 设计模式(1)-带你了解3类8种单例模式 | Java技术经验分享 Java时间处理5---Java8中时区相关类库介绍 | Java技术经验分享 Java时间处理4---Java8中LocalDate、LocalTime、LocalDateTime介绍 | Java技术经验分享 Java时间处理3---Java8中Instant、Duration、Period、Clock介绍 | Java技术经验分享 一些有意思的问答 | Java技术经验分享 Nacos系列博客说明 | Java技术经验分享 菜鸡程序员的2019年度总结 | Java技术经验分享 Java中“附近的人”实现方案讨论及代码实现 | Java技术经验分享 Java时间处理2----时区TimeZone类方法探究(Java8以前) | Java技术经验分享 Java时间处理1----Date和Calendar方法探究(Java8以前) | Java技术经验分享 FastJson中JSONString、JavaBean、JSONObject、JSONArray的转换关系及API示例 | Java技术经验分享 2019.11软考软件设计师归来心得体会及复习备考指南 | Java技术经验分享 你还没用过“约定式提交”吗?那你赶紧来补补知识吧 | Java技术经验分享 教你如何看懂UML中的类图及类图中的关系 | Java技术经验分享 设计模式总览 | Java技术经验分享 萌新入门Github请看这里,学不会远程教 | Java技术经验分享 Hexo的工作原理探究 | Java技术经验分享 Hexo-theme-butterfly修改调整记录教程 | Java技术经验分享
设计模式(4)-建造者模式 | Java技术经验分享
文章作者: LarsCheng · 2020-09-29 · via Java技术经验分享

概念

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

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

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

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

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

模拟场景

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

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

传统实现方式

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

  • 抽象电脑类
  • 具体电脑类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 {

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电源'}

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

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

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