JAVA设计模式总结—建造者模式
建造者模式
模式动机与定义
首先建造者模式的动机是为了创建复杂对象,简化传统的创建方法,提高创建的效率和可读性。

像图中的这个例子,用户的需求是驾驶一辆汽车,但是对于用户来说是不需要了解汽车装配厂汽车的具体装配过程,用户只是使用汽车整个整体。
所以在这个例子中,用户只需要知道我要类型为汽车的对象就够了,而不需要知道这个复杂对象到底是怎么组成的,我理解的就是, 建造者模式就是提供一个接口,实现接受用户一个汽车类型的参数,然后通过内部建造,返回一个汽车对象。
模式结构与分析
模式定义
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。
构建过程:汽车的组装过程
不同的表示: 构建不同的汽车,比如有轿车,电动汽车,运动型汽车比如,汽车有很多组成部分,但是用户不需要每个组成部分都要指定,用户可以通过指定汽车的一些特点,比如电动车,自动挡这些特征,就可以创建一辆车的对象, 但是具体车是怎么组装的,什么先后顺序,其他没有指定的部分的特征,比如车的高度就不需要知道。
- 将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可
- 关注如何逐步创建一个复杂的对象,不同的建造者定义了不同的创建过程
模式结构

- Product: 最终要生成的对象,例如 Computer实例。
- Builder: 构建者的抽象基类(有时会使用接口代替)。其定义了构建Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法
Product getProduct()。 - ConcreteBuilder: Builder的实现类。
- Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法
void Construct(Builder builder), 在这个方法中通过调用builder的方法,就可以设置builder,等设置完成后,就可以通过builder的getProduct()方法获得最终的产品。
时序图

模式实例与解析

比如有一个老板现在需要造一个高楼,这个老板在建造者模式就是一个客户类(client),调用Director的建造方法,然后建造者模式中的指挥者类(Director)就相当于是一个包工头,他把建造的工作分配给底下的工人,而不同的工人可以建造的房屋类型不同,就比如有些工人只会建造普通的屋子,有些工人可以建造高楼这些工人就是具体的建造者(ConcreteBuilder),指挥者就通过客户端的需求给具体的工人分配工作,建造不同的房屋,房屋就是建造者模式里的产品类(product)
参考类图

相比之前的标准建造者类图,该类图多了一个Client客户类,客户类依赖指挥者类和具体的建造者类,具体的建造者和product是依赖关系,具体的建造者继承抽象建造者,指挥者和抽象建造是聚合关系。
参考代码
Product:产品,对应例子中的房子
public class House {
// 地基
private String baise;
// 墙面
private String wall;
// 屋顶
private String roofed;
@Override
public String toString() {
return "House{" +
"baise='" + baise + '\'' +
", wall='" + wall + '\'' +
", roofed='" + roofed + '\'' +
'}';
}
/**
* get set方法
*/
}
Builder: 抽象的建造者,对应例子中的工人
public abstract class HouseBuilder {
protected House house = new House();
// 将建造的流程写好抽象的方法
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void buildRoofed();
// 房子建造好,将房子返回
public House buildHouse() {
System.out.println(house);
return house;
}
}
ConcreteBuilder: 具体的建造者,对应例子中的具体工人
// 盖普通房子的工人
public class CommonHouse extends HouseBuilder{
@Override
public void buildBasic() {
System.out.println("普通房子打地基5m");
house.setBaise("5m");
}
@Override
public void buildWalls() {
System.out.println("普通房子砌墙10cm");
house.setWall("10cm");
}
@Override
public void buildRoofed() {
System.out.println("普通房子屋顶");
house.setRoofed("common");
}
}
// 盖高楼的工人
public class HighBuilding extends HouseBuilder{
@Override
public void buildBasic() {
System.out.println("高房打地基10m");
house.setBaise("10m");
}
@Override
public void buildWalls() {
System.out.println("高楼砌墙20cm");
house.setWall("20cm");
}
@Override
public void buildRoofed() {
System.out.println("高楼屋顶");
house.setRoofed("high");
}
}
Director: 指挥者类,这里对应例子中的包工头
// 指挥者,这里去指定制作流程,返回产品
public class HouseDirector {
HouseBuilder houseBuilder = null;
// 构造器传入houseBuilder
public HouseDirector(HouseBuilder houseBuilder){
this.houseBuilder = houseBuilder;
}
// 通过set传入houseBuilder
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
// 指挥HouseBuilder如何建造房子,建造房子的流程
public House constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.buildRoofed();
return houseBuilder.buildHouse();
}
}
Client: 客户类,这里对应例子中的老板
public class Client {
public static void main(String[] args) {
// 盖普通房子
CommonHouse commonHouse = new CommonHouse();
// 准备盖普通房子的指挥者
HouseDirector houseDirector = new HouseDirector(commonHouse);
// 完成盖房子,返回产品
House house = houseDirector.constructHouse();
}
}
运行结果:
普通房子打地基5m
普通房子砌墙10cm
普通房子屋顶
House{baise='5m', wall='10cm', roofed='common'}
建造者模式在JDK中的应用和源码分析
StringBuilder
下面的例子是StringBuilder的简单应用
public class Builder {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("hello,");
stringBuilder.append("world");
System.out.println(stringBuilder);
}
}
现在来看一下StringBuilder的定义
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuilder>, CharSequence{
...
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
...
}
可以看到StringBuilder在调用append方法后,是使用了super的方法进行调用,StringBuilder在此充当了指挥者角色,同时充当了具体的建造者,建造方法的实现是由AbstractStringBuilder完成,而StringBuilder继承了AbstractStringBuilder,所以接下来我们再来看看AbstractStringBuilder的定义
abstract class AbstractStringBuilder implements Appendable, CharSequence {
...
public AbstractStringBuilder append(StringBuffer sb) {
return this.append((AbstractStringBuilder)sb);
}
...
}
AbstractStringBuilder 实现了 Appendable接口方法,这里的AbstractStringBuilder 已经是建造者,只是不能实例化
public interface Appendable {
Appendable append(CharSequence csq) throws IOException;
Appendable append(CharSequence csq, int start, int end) throws IOException;
Appendable append(char c) throws IOException;
}
Appendable接口定义了多个append方法(抽象方法),即Appendable为抽象建造者,定义了抽象方法
模式效果与应用
建造者模式优点:
客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
每一个具体建造者都相对独立,与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,扩展方便,符合开闭原则
可以更加精细地控制产品的创建过程
建造者模式缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,不适合使用建造者模式,因此其使用范围受到一定的限制
- 如果产品的内部变化复杂,可能会需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加了系统的理解难度和运行成本
在以下情况下可以使用建造者模式:
需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量
需要生成的产品对象的属性相互依赖,需要指定其生成顺序
对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中
隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
JAVA设计模式总结—建造者模式的更多相关文章
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
- Java 设计模式之建造者模式(四)
原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...
- java设计模式3——建造者模式
java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...
- Java设计模式之建造者模式(Builder)
前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...
- Java设计模式之三 ----- 建造者模式和原型模式
前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...
- Java设计模式之三建造者模式和原型模式
建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.简单的来说就是将一个复杂的东西 ...
- java设计模式之建造者模式
学习了设计模式,一直感觉有进步又没有进步,与同学.同事探讨了一下.变化不可能一会就可以的,需要努力坚持.不管进步大小,也不管是否进步,做到勿忘初心,做自己喜欢的事情就好.还有几个设计模式一直没有写,原 ...
- java设计模式之四建造者模式(Builder)
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到 ...
- java设计模式3.建造者模式、原型模式
建造者模式 一个产品常有不同的组成部分作为产品的零件,有些情况下,一个对象会有一些重要的性质,在它们没有恰当的值之前,对象不能作为一个完整的产品使用,有些时候,一个对象的一些性质必须按照某个顺序赋值才 ...
随机推荐
- babel 的介绍及其配置
vue/cli -- babel Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其 ...
- Codeforces Round #671 (Div. 2) B. Stairs 难度1200
题目链接: Problem - 1419B - Codeforces 题目 题意 给x个格子,你可以用这x个格子去拼成楼梯 好的楼梯的要求如下: 1. 第n列有n个格子 2. 这个楼梯的所有格子可以被 ...
- python基础练习题(题目 将一个整数分解质因数。例如:输入90,打印出90=2*3*3*5)
day9 --------------------------------------------------------------- 实例014:分解质因数 题目 将一个整数分解质因数.例如:输入 ...
- python学习-Day19
目录 今日内容详细 正则表达式 开端 概念及相关符号 正则表达式之字符组 正则表达式之特殊符号 正则表达式之量词 小试牛刀 实现手机号码校验功能 复杂正则的编写 校验用户身份证号码 校验邮箱.快递单号 ...
- Windows下使用 Docker 部署 RabbitMQ
安装 Docker 首先进入 https://docs.docker.com/desktop/windows/install/ 下载最新版 Docker,下载好后,双击进行安装,此处不对安装进行说明. ...
- C# 核心
C# 核心 面向对象编程概念 面向过程编程是一种以过程为中心的编程思想,分析出解决问题所需要的步骤,然后有函数把步骤一步一步实现,使用的时候一个一个依次调用. 面向对象是一种对现实世界理解和抽象的编程 ...
- Linux-3作业练习
1.自建yum仓库,分别为网络源和本地源 请移步: yum源配置 2.编译安装http2.4,实现可以正常访问,并将编译步骤和结果提交. 请移步:http2.4编译安装 总结参照https ...
- GDB调试小白教程
1.GDB是什么? 想必很多人都用过windows下各种编译器软件的调试功能,例如Visio Studio里面"断点"."开始调试"."逐语句&quo ...
- UNIAPP实现PDA扫码
目前我接触到了两种方法,以扫码pda安卓采集器(可以直接理解为手机上有个激光扫码)的设置划分. 1.扫描设置 --> 键盘方式输出(键盘类型:物理键盘),注意设置要看具体的型号: 2.扫码设置 ...
- Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析
Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析 前言 上一篇文章Spring Ioc源码分析系列--Ioc源码入口分析已经介绍到Ioc容器 ...