建造者模式——链式调用

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。


哈喽,大家好,我是一条~

之前的《白话设计模式》因为工作被搁置,如今再次启航,并搭配框架源码解析一起食用,将理论与实战完美结合。

对设计模式不是很熟悉的同学可以先看一下《23种设计模式的一句话通俗解读》全面的了解一下设计模式,形成一个整体的框架,再逐个击破。

上期原型模式发布以后,收到了粉丝的感谢,一条创作的动力更足了。

今天我们一块看一下建造者模式,同样是创建型设计模式。

定义

官方定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

通俗解读

提供一种创建对象的方式,创建的东西细节复杂,还必须暴露给使用者。屏蔽过程而不屏蔽细节

类似建房子,只需要把材料和设计图纸给工人,就能建成想要的房子,不关注工人建房子的过程,但对于细节,我们又可以自己设计。

结构图

代码演示

本文源码:建造者模式 提取码: vpqt

目录结构

建议跟着一条学设计模式的小伙伴都建一个maven 工程,并安装lombok依赖和插件。

并建立如下包目录,便于归纳整理。


pom如下

1
2
3
4
5
xml复制代码    <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>

开发场景

现在有一个手机的建造者,我要让它为我生产不用品牌和配置的手机。该怎么实现?

代码演示

1.创建手机类

1
2
3
4
5
6
7
8
9
10
11
java复制代码@Data
public class Phone {
//处理器
protected String cpu;
//内存
protected String mem;
//磁盘
protected String disk;
//屏幕大小
protected String size;
}

2.创建建造者接口

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码//定义建造者的模板方法
public interface Builder {
Phone phone = new Phone();
void buildCpu(String cpu);
void buildMem(String mem);
void buildDisk(String disk);
void buildSize(String size);

default Phone getPhone(){
return phone;
}
}

3.创建Vivo手机的建造者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
java复制代码public class VivoPhoneBuilder implements Builder{
//建造者细节的实现
@Override
public void buildCpu(String cpu) {
phone.cpu=cpu;
}

@Override
public void buildMem(String mem) {
phone.mem=mem;
}

@Override
public void buildDisk(String disk) {
phone.disk=disk;
}

@Override
public void buildSize(String size) {
phone.size=size;
}
}

4.创建测试类

1
2
3
4
5
6
7
8
9
10
11
java复制代码public class MainTest {
public static void main(String[] args) {
VivoPhoneBuilder builder = new VivoPhoneBuilder();
builder.buildCpu("888");
builder.buildDisk("512");
builder.buildMem("16");
builder.buildSize("plus");
Phone phone = builder.getPhone();
System.out.println(phone);
}
}

5.输出结果

如果我这时需要生产OPPO手机,只需新建一个OppoPhoneBuilder实现Builder接口即可。

链式调用

相信大家在开发中都遇见过这样的代码,像链子一样可以一直调用下去。

那么如何实现链式建造者呢?

有以下两种方式:

1.修改返回值为Builder

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码public interface Builder {
Phone phone = new Phone();
// void 改为 Builder 同步修改实现类
Builder buildCpu(String cpu);
Builder buildMem(String mem);
Builder buildDisk(String disk);
Builder buildSize(String size);

default Phone getPhone(){
return phone;
}
}

测试1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码public class MainTest {
public static void main(String[] args) {
// ……

VivoPhoneBuilder builder2 = new VivoPhoneBuilder();
Phone phone1 = builder2
.buildCpu("888")
.buildDisk("512")
.buildMem("16")
.buildSize("plus")
.getPhone();
System.out.println("phone1:"+phone1);
}
}

结果1

2.使用lombok

1
2
3
4
5
6
7
java复制代码@Data
@Builder //使用链式建造者
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
// ……
}

测试2

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码public class MainTest {
public static void main(String[] args) {

// ……

Phone build = Phone.builder()
.cpu("888")
.mem("16")
.disk("512")
.size("plus").build();
System.out.println("builder:"+build);
}
}

结果2

应用场景

  • StringBuilder:append(); 给谁append呢?
1
2
3
4
5
6
7
8
9
java复制代码    public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
  • Swagger-ApiBuilder;
  • 快速实现:Lombok-@Builder

总结

建造者模式提供了对于同一构建过程的不同表示,像流水线一样生产对象。对于新增的对象,只需要创建对应的建造者即可,不需要修改源代码。

lombok为我们提供了建造者模式的快速实现(@Builder),要应用到实际编码中。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%