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. 实验3:OpenFlow协议分析实践

    作业链接:实验3:OpenFlow协议分析实践 一.实验目的 能够运用 wireshark 对 OpenFlow 协议数据交互过程进行抓包: 能够借助包解析工具,分析与解释 OpenFlow协议的数据 ...

  2. 使用Golang搭建gRPC服务提供给.NetCore客户端调用

    目录 gRPC概述 RPC gRPC又是什么呢 安装 Golang IDE(Goland) Protocol Buffer 下载Protocal Buffer 配置Protocal Buffer编译器 ...

  3. WEB 标准以及 W3C 的理解与认识

    01.  WEB标准 ①  web标准 简单来说可以分为结构.表现和行为. ②  结构:主要是有HTML标签组成(通俗点说,在页面body里面我们写入的标签都是为了页面的结构)   表现:即指css样 ...

  4. 试题 算法训练 最大最小公倍数 java题解

    资源限制 时间限制:1.0s   内存限制:256.0MB 问题描述 已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少. 输入格式 输入一个正整数N. 输出格式 输出一个整数 ...

  5. 设置elementUI的table组件滚动条位置

    1.设置table的ref为tableList 2.设置滚动至顶部 this.$refs.tableList.bodyWrapper.scrollTop =0; 3.设置滚动至底部 this.$ref ...

  6. TypeError: Restaurant() takes no arguments

    1. 错误描述 TypeError: Restaurant() takes no arguments 2. 原因:在编写__init__时,pycharm会自动添加关键字,有时会直接写称整型int, ...

  7. [敏捷软工团队博客]Beta设计和计划

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业要求 Beta设计和计划 我们在这个课程的目标是 在团队合作中锻炼自己 这个作业在哪个具体方面帮助我们实现目标 对Beta ...

  8. CSP-S 2021 遗言

    感谢€€£,谢谢宁嘞! 第一题,€€£给了很多限制条件,什么"先到先得"."只有一个跑道",让它看起来很好做,然后来骗,来偷袭,广大"消费者" ...

  9. Spring Cloud Alibaba环境搭建

    前言:Spring Cloud Alibaba是目前主流的分布式微服务架构,本文主要讲解了在IDEA中如何搭建Spring Cloud Alibaba环境,以及介绍Spring Cloud Aliba ...

  10. 从0到1搭建自己的组件(vue-code-view)库(下)

    0x00 前言 书接上文,本文将从源码功能方面讲解下 vue-code-view 组件核心逻辑,您可以了解以下内容: 动态组件的使用. codeMirror插件的使用. 单文件组件(SFC,singl ...