1、什么是建造者模式

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

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

说人话:将构造复杂对象的过程和组成对象的部件解耦。就像攒电脑一样,不管什么品牌的配件,只要兼

容就可以装上;同样,一样的配件,可以有好多组装的方式。更直接点就是同一个类,通过内部不同属性状态构造不同的对象。

2、建造者模式定义

在建造者模式中,有 4 个定义:

①、Product(产品类) :我们具体需要生成的类对象

②、Builder(抽象建造者类):为我们需要生成的类对象,构建不同的模块属性,即:公开构建产品类的属性,隐藏产品类的其他功能。

③、ConcreteBuilder(具体建造者类):实现抽象类定义的所有方法,并返回一个组建好的对象。

④、Director(导演类):确定构建我们的类对象具体有哪些模块属性,在实际应用中可以不需要这个角色,直接通过client处理。

3、实例

比如我们去买车,一般同一辆车会有多个版本,根据配置不一样,分为经典版、舒适版、豪华版等,比如经典版是手动挡手动座椅,舒适版是自动挡全景天窗等。

public class Car {
// 车名称
private String name;
// 自动挡
private String automaticCatch;
// 手动挡
private String manualTransmission;
// 全景天窗
private String panoramicSunroof;
// 自动座椅
private String automaticSeat;
// 手动座椅
private String manualSeat;
// 倒车影像
private String reversingImage; //省略get/set方法
}

3.1 普通实现

public class GeneralTest {
public Car getCarInstance(String carName){
Car car = new Car();
if("经典版".equals(carName)){
car.setName("经典版");
car.setManualTransmission("手动挡");
}else if("舒适版".equals(carName)){
car.setName("舒适版");
car.setAutomaticCatch("自动挡");
car.setManualSeat("手动座椅");
}else if("豪华版".equals(carName)){
car.setName("豪华版");
car.setAutomaticCatch("自动挡");
car.setAutomaticSeat("自动座椅");
car.setReversingImage("倒车影像");
car.setPanoramicSunroof("全景天窗");
}else{
throw new IllegalArgumentException("carName is error: carName="+carName);
}
return car;
}
}

注意,并不是说高版本汽车一定具有低版本所有配置,比如舒适版配置是手动座椅,豪华版是自动座椅,而且不同版本之间配置有交叉。

从上面可以看出,根据汽车类型,我们可以创建相应配置的汽车,但其实汽车的配置是有很多的,种类一旦多了,上面的代码就会显得很臃肿,也不好维护,于是我们用建造者模式来重构。

3.2 建造者模式实现

①、创建抽象建造者类

public abstract class CarBuilder {

    public abstract Car buildClassic();

    public abstract Car buildComfortable();

    public abstract Car buildLuxury();

}

②、创建具体建造者类。对抽象建造者类的抽象方法进行实现赋值,达到我们所需要的结果。

public class CarConcreteBuilder extends CarBuilder{

    @Override
public Car buildClassic() {
Car car = new Car();
car.setName("经典版");
car.setManualTransmission("手动挡");
return car;
} @Override
public Car buildComfortable() {
Car car = new Car();
car.setName("舒适版");
car.setAutomaticCatch("自动挡");
car.setManualSeat("手动座椅");
return car;
} @Override
public Car buildLuxury() {
Car car = new Car();
car.setName("豪华版");
car.setAutomaticCatch("自动挡");
car.setAutomaticSeat("自动座椅");
car.setReversingImage("倒车影像");
car.setPanoramicSunroof("全景天窗");
return car;
}
}

③、创建我们的导演类,指导我们怎么去创建对象

public class CarDirector {
private CarBuilder carBuilder; public CarDirector(CarBuilder carBuilder){
this.carBuilder = carBuilder;
} public Car classicConstruct(){
return carBuilder.buildClassic();
} public Car comfortableConstruct(){
return carBuilder.buildComfortable();
} public Car luxuryConstruct(){
return carBuilder.buildLuxury();
}
}

④、测试

public class BuilderTest {
public static void main(String[] args) {
CarBuilder carBuilder = new CarConcreteBuilder();
CarDirector carDirector = new CarDirector(carBuilder);
Car classicCar = carDirector.classicConstruct();
System.out.println(classicCar);
Car comfortableCar = carDirector.comfortableConstruct();
System.out.println(comfortableCar);
}
}

另外,对于不同配置之间有互斥关系,比如有了手动挡,就不可能有自动挡,属性之间的关系我们也可以在具体建造者类 CarConcreteBuilder 进行设置。

4、与工厂模式区别

前面我们介绍工厂模式时说了由工厂类来负责创建对象,而建造者模式也是让具体建造者类负责创建对象,那这两者有什么区别呢?

实际上工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。而建造者模式是用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。

有这样一个例子可以形象的解释:

顾客走进一家餐馆点餐,我们利用工厂模式,根据用户不同的选择,来制作不同的食物,比如披萨、汉堡、沙拉。对于披萨来说,用户又有各种配料可以定制,比如奶酪、西红柿、起司,我们通过建造者模式根据用户选择的不同配料来制作披萨。

5、建造者模式优点

①、封装性

使用建造者模式可以使客户端不必知道产品内部组成的细节, 如例子中我们就不需要关心每一种版本汽车内部是如何实现的, 产生的对象类型就是Car。

②、建造者独立,容易扩展

其实对于上面例子中的 CarConcreteBuilder 类,有三个方法,分别构造经典版、舒适版、豪华版汽车,每个方法内部是不受影响的,或者我们还可以直接把这一个类拆成三个类。

③、便于控制细节风险

由于具体每个建造者过程是独立的,因此可以对过程更加细化,而不会对其它模块产生影响。

6、建造者模式使用场景

①、相同的方法, 不同的执行顺序, 产生不同的事件结果时, 可以采用建造者模式。

②、多个部件或零件, 都可以装配到一个对象中, 但是产生的运行结果又不相同时, 则可以使用该模式。

③、产品类非常复杂, 或者产品类中的调用顺序不同产生了不同的效能, 这个时候使用建造者模式非常合适。

Java设计模式之(三)——建造者模式的更多相关文章

  1. Java设计模式14:建造者模式

    什么是建造者模式 发现很多框架的源码使用了建造者模式,看了一下觉得挺实用的,就写篇文章学习一下,顺便分享给大家. 建造者模式是什么呢?用一句话概括就是建造者模式的目的是为了分离对象的属性与创建过程,是 ...

  2. Java设计模式学习记录-建造者模式

    前言 今天周末,有小雨,正好也不用出门了,那就在家学习吧,经过了两周的面试,拿到了几个offer,但是都不是自己很想去的那种,要么就是几个人的初创小公司,要么就是开发企业内部系统的这种传统开发,感觉这 ...

  3. java设计模式-----6、建造者模式

    Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类 ...

  4. Java设计模式学习三-----工厂模式

    工厂模式 工厂模式(Factory Pattern)是Java中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻 ...

  5. Java设计模式之(建造者模式)

    建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式通常包括下面几个角色: 1. builder:抽象建造者,给出一个抽象接口,以规范产品对象的各个组 ...

  6. JAVA设计模式之【建造者模式】

    建造者模式 建造者模式为客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品 角色 Builder抽象建造者 buildPartX getResult ConcreteBuilder具体建 ...

  7. 【java设计模式】-05建造者模式

    建造者模式 简述 建造者模式,是将一个复杂对象的创建和它的表示分离开来,这就使得同样的构建构成可以有不同的表示. 建造者模式是一步步构建一个复杂的对象,允许用户只需要指定复杂对象的类型和必要的内容就可 ...

  8. 重学 Java 设计模式:实战建造者模式

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 乱码七糟 [luàn qī bā zāo],我时常怀疑这个成语 ...

  9. 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)

    作者:小傅哥 博客:https://bugstack.cn - 编写系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为什么你的代码那么多ifelse 同类的业务.同样的功能, ...

  10. 重学 Java 设计模式:实战外观模式「基于SpringBoot开发门面模式中间件,统一控制接口白名单场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你感受到的容易,一定有人为你承担不容易 这句话更像是描述生活的,许许多多的磕磕绊绊总 ...

随机推荐

  1. 【Golang】Go 通过结构(struct) 实现接口(interface)

    一.通过结构(struct) 实现 接口(interface) 1.在了解iris框架的时候,经常看到有这样去写的使用一个空结构体作为接收器,来调用方法,有点好奇这样做有什么意义. 解释:在 Go 语 ...

  2. Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  3. 题解 [HAOI2018]反色游戏

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条无向边的图,每个点都有一个 \(\in [0,1]\) 的权值,每次可以选择一条边,然后将该边相连两点权值异或上 \(1\).问有多少种 ...

  4. 洛谷2543AHOI2005]航线规划 (树剖+线段树+割边思路)

    这个题的思路还是比较巧妙的. 首先,我们发现操作只有删除和询问两种,而删除并不好维护连通性和割边之类的信息. 所以我们不妨像WC2006水管局长那样,将询问离线,然后把操作转化成加边和询问. 然后,我 ...

  5. bzoj2038 小z的袜子 (莫队)

    题目大意 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编 ...

  6. python png图片生成gif

    有时候写代码就是这样别人把代码写好你在后面加一个句号就行了 我很懒不想写成函数,你自己来吧.有注释就不错了 这个依赖一个图像处理库pillow,轮子就是轮他不是车 import imageio imp ...

  7. 是兄弟就来摸鱼 Scrum Meeting 博客汇总

    是兄弟就来摸鱼 Scrum Meeting 博客汇总 一.Alpha阶段 第一次Scrum meeting 第二次Scrum meeting 第三次Scrum meeting 第四次Scrum mee ...

  8. OO_JAVA_JML系列作业_单元总结

    OO_JAVA_JML系列作业_单元总结 (1)梳理JML语言的理论基础.应用工具链情况 简单梳理 以下三者是jml规格里的核心,对一个方法功能和属性的限制: requires子句:规定方法的前置条件 ...

  9. 洛谷 P3232 [HNOI2013]游走

    链接: P3232 题意: 和上次考试 T4 的简化且无修改一样,经典图上高斯消元求期望. 分析: 要求出每个点的期望出发次数 \(f_i\),每个点度数为 \(d_i\),有 \[f1=\sum\d ...

  10. .NET 5 全自动分表组件,.NET 分表方案 ,分表架构与设计

    一.疑问&目的 1.1 分表使用场景 (1)可扩展架构设计,比如一个ERP用5年不卡,到了10就卡了因为数据太多了,这个时候很多人都是备份然后清空数据,这个工作大并且麻烦,以前的数据很难在使用 ...