哈喽,大家好,我是一条~
之前的《白话设计模式》因为工作被搁置,如今再次启航,并搭配「框架源码解析」一起食用,将理论与实战完美结合。
对设计模式不是很熟悉的同学可以先看一下《23种设计模式的一句话通俗解读》,全面的了解一下设计模式,形成一个整体的框架,再逐个击破。
上期原型模式发布以后,收到了粉丝的感谢,一条创作的动力更足了。
今天我们一块看一下「建造者模式」,同样是创建型设计模式。
定义
「官方定义」
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
「通俗解读」
提供一种创建对象的方式,创建的东西细节复杂,还必须暴露给使用者。「屏蔽过程而不屏蔽细节」。
类似建房子,只需要把材料和设计图纸给工人,就能建成想要的房子,不关注工人建房子的过程,但对于细节,我们又可以自己设计。
结构图
代码演示
本文源码:点击底部阅读原文 提取码: vpqt
目录结构
建议跟着一条学设计模式的小伙伴都建一个maven
工程,并安装lombok
依赖和插件。
并建立如下包目录,便于归纳整理。
pom
如下
<dependency> | |
<groupId>org.projectlombok</groupId> | |
<artifactId>lombok</artifactId> | |
<version>1.16.10</version> | |
</dependency> | |
开发场景
现在有一个手机的建造者,我要让它为我生产不用品牌和配置的手机。该怎么实现?
代码演示
「1.创建手机类」
public class Phone { | |
//处理器 | |
protected String cpu; | |
//内存 | |
protected String mem; | |
//磁盘 | |
protected String disk; | |
//屏幕大小 | |
protected String size; | |
} |
「2.创建建造者接口」
//定义建造者的模板方法 | |
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
手机的建造者」
public class VivoPhoneBuilder implements Builder{ | |
//建造者细节的实现 | |
public void buildCpu(String cpu) { | |
phone.cpu=cpu; | |
} | |
public void buildMem(String mem) { | |
phone.mem=mem; | |
} | |
public void buildDisk(String disk) { | |
phone.disk=disk; | |
} | |
public void buildSize(String size) { | |
phone.size=size; | |
} | |
} | |
「4.创建测试类」
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
」
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」
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
」
@Data | |
@Builder //使用链式建造者 | |
@NoArgsConstructor | |
@AllArgsConstructor | |
public class Phone { | |
// …… | |
} |
「测试2」
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呢?
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
),要应用到实际编码中。
一篇优质的原创文真的很耗费作者的心血,所以如果感觉写的还不错,麻烦点个「关注」,这对一条来说很重要,也是一条创作下去的动力!