前言

建造者模式(Builder Pattern)又称为创建者模式,建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在该模式中存在一个Builder类,这个类是独立于其他对象的,在建造者模式中使用Builder类一步一步的构造最终的对象。

记得在刚开始接触web开发的时候,后端在接收到前端请求的参数时,后端需要不断的使用set函数来构造一个对象,比如现在需要构造一个Student类,但是我就写了这么一串又臭又长的代码。

Student student = new Student();
student.setId("id");
student.setName("1999single");
student.setGrade("17");
student.setMajor("软件工程");
... ...

是吧,看着头疼,写着也头疼。直到接触到了建造者模式,心中的太阳升起来了……

介绍

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:产品:创建的实力,建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的
StringBuilder。

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

结构

产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。

抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法。

具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。

指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

实现

既然称作建造者模式,这里就建造一座房子好勒!假设一种房子有四种属性:几楼、什么样的门、什么样的窗户、外墙是什么颜色的。

/*** Product(产品角色)*/
public class House {private String storey;private String door;private String window;private String color;public String getStorey() {return storey;}public void setStorey(String storey) {this.storey = storey;}public String getDoor() {return door;}public void setDoor(String door) {this.door = door;}public String getWindow() {return window;}public void setWindow(String window) {this.window = window;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "House{" +"storey='" + storey + '\'' +", door='" + door + '\'' +", window='" + window + '\'' +", color='" + color + '\'' +'}';}
}

还需要有一个建筑队,他们有着建造房子的技术。

/*** Builder(抽象建造者)*/
public interface HouseBuilder {void buildStorey();void buildDoor();void buildWindow();void buildColor();House build();
}public class ChinaHouseBuilder implements HouseBuilder {private House house;public ChinaHouseBuilder() {this.house = new House();}@Overridepublic void buildStorey() {house.setStorey("5");}@Overridepublic void buildDoor() {house.setDoor("steel door");}@Overridepublic void buildWindow() {house.setWindow("steel window");}@Overridepublic void buildColor() {house.setColor("white");}@Overridepublic House build() {return house;}}

此时还需要一个指挥的人,选取善于修建中式的房屋的建筑队还是善于修建复式房屋的建筑队,以及告诉建筑队该房屋需要建哪一些东西,比如我就觉得房子的外装没必要,不如把外装的钱省下来用在内装!!内在美才是真的美!!

public class Director {public House bulidHouse(HouseBuilder builder) {builder.buildStorey();builder.buildDoor();builder.buildWindow();builder.buildColor();return builder.build();}
}

最后当然就是老板出钱盖房子咯(调用)

public class Main {public static void main(String[] args) {Director director = new Director();House house = director.bulidHouse(new ChinaHouseBuilder());System.out.println(house);}
}

到这里一个简单的建造者模式就构建完成了,我们发现每一个Builder子类的都非常的独特(写得死),假如我要修建一个6楼的房子我又需要新建一个Builder子类,假如我不要窗户又得新建一个Builder子类,这也是建造者模式的缺点。

为了解决这个缺点,又产生了建造者模式的链式方法,同时也提高了代码编写的舒适度。

链式调用

有些朋友可能不熟悉什么是链式调用,咱们拿两个在实际项目中的例子来说明,一样就是看出所谓链式是什么意思。

// 安卓的一个加载图片的库,基于建造者模式和链式调用的思想诞生的。
Glide.with(context) // context为安卓开发中的上下文.load(internetUrl) // internetUrl网络图片的地址.into(targetImageView); // targetImageView为现实图片的一个组件/容器// okhttp中创建request的方法
Request request = new Request.Builder().url(url) // 请求的url.get() // 设置请求的方式为GET,相应的还有.post()方法.build(); // 建造对象的最后一步

可以看出他们共同的特点就是不断的 .().().().().().() 写代码的舒适性立马提高,接下来我们来讨论下如何实现这样的链式结构

链式调用实现

我们还是使用上面的造房子的例子来说明

// product
public class House {private String storey;private String door;private String window;private String color;public House(String storey, String door, String window, String color) {this.storey = storey;this.door = door;this.window = window;this.color = color;}public House() {}public String getStorey() {return storey;}public void setStorey(String storey) {this.storey = storey;}public String getDoor() {return door;}public void setDoor(String door) {this.door = door;}public String getWindow() {return window;}public void setWindow(String window) {this.window = window;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "House{" +"storey='" + storey + '\'' +", door='" + door + '\'' +", window='" + window + '\'' +", color='" + color + '\'' +'}';}// product中静态的方法生成一个Builderpublic static HouseBuilder builder() {return new HouseBuilder();}// Builderpublic static class HouseBuilder {private String storey;private String door;private String window;private String color;public String getStorey() {return storey;}// 返回自身对象,用于下一步的调用public HouseBuilder storey(String storey) {this.storey = storey;return this;}public String getDoor() {return door;}public HouseBuilder door(String door) {this.door = door;return this;}public String getWindow() {return window;}public HouseBuilder window(String window) {this.window = window;return this;}public String getColor() {return color;}public HouseBuilder color(String color) {this.color = color;return this;}// 最后构建Housepublic House bulid() {return new House(storey, door, window, color);}}
}

调用:

House house = House.builder().storey("2").window("not").door("kk").color("blue").build();

Lombok中的建造者模式(链式调用)

使用Lombok可以非常快速的实现类的建造者模式,我们还是对House进行操作

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
public class House {private String storey;private String door;private String window;private String color;}

好的,写完了,晚安!使用Lombok就是这么方便,什么Builder什么Director都不要了。

再来看一下调用,也非常的简单。

House hh = House.builder().storey("3").color("black").window("wooden").door("wooden").bulid();

Lombok实现建造者原理(简单说说)

首先我们反编译一下编译器生成的House.class得到

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package builderPattern;public class House {private String storey;private String door;private String window;private String color;public static House.HouseBuilder builder() {return new House.HouseBuilder();}public House() {}public House(String storey, String door, String window, String color) {this.storey = storey;this.door = door;this.window = window;this.color = color;}public String getStorey() {return this.storey;}public String getDoor() {return this.door;}public String getWindow() {return this.window;}public String getColor() {return this.color;}public void setStorey(String storey) {this.storey = storey;}public void setDoor(String door) {this.door = door;}public void setWindow(String window) {this.window = window;}public void setColor(String color) {this.color = color;}public static class HouseBuilder {private String storey;private String door;private String window;private String color;HouseBuilder() {}public House.HouseBuilder storey(String storey) {this.storey = storey;return this;}public House.HouseBuilder door(String door) {this.door = door;return this;}public House.HouseBuilder window(String window) {this.window = window;return this;}public House.HouseBuilder color(String color) {this.color = color;return this;}public House build() {return new House(this.storey, this.door, this.window, this.color);}}
}

为了便于阅读代码我删掉了一些于建造者模式无关的代码(使用注解后Lombok还会自动生成toString方法和hashCode方法),其实Lombok只是自动帮我们生成了代码而已,实际上还是这么一个思路:–>创建Bulider–>开始建造–>最后bulid。

至于Lombok是怎么实现动态生成代码,这就要追溯他的原理的,首先他的注解是用于source的,java编译成class后,注解就不存在于字节码文件中了,所以Lombok其实是在代码编译时期动态的生成代码插入到编译树中的。(关于编译原理不说太多了,这学期刚挂科。有时间再自己实现一下Lombok的@ToString注解,有兴趣的朋友可以关注一下我!挂科博主耻辱下线,晚安。)


❤❤❤ 只需要捐献一个赞就能实现孩子的成为架构师梦想

Java设计模式 建造者模式相关推荐

  1. Java 设计模式——建造者模式(Builder Pattern)

    前言 一.简介 ​二.实现方式 三.常见第一种方式 (1)一般有以下几个角色 (2)举个例子 (3)具体步骤 (4)具体代码 三.第二种方式 (1)主要有三个角色:抽象建造者.具体建造者.产品 (2) ...

  2. 我的Java设计模式-建造者模式

    在未上大学之前,一直有个梦想"I have a dream!",就是能成为一位汽车工程师,一直幻想着开着自己设计的汽车飞奔在公路上,迷倒了万千少女.咳咳~~虽然现在没实现我的dre ...

  3. 设计建造者模式java代码,Java设计模式-建造者模式

    定义 Separate the construction of a complex object from its representation so that the sameconstructio ...

  4. java设计模式-建造者模式

    概念:使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. ...

  5. Java设计模式-建造者模式 理论代码相结合

    继工厂模式后的建造者模式,也是java中常常能够见到的模式一种,应用场景也比较广,比较好用. 大家想了解的话,一起来看一看啦.

  6. JAVA设计模式--建造者模式

    目录 前言 一.什么是建造者模式 二.建造者模式的结构 三.建造者模式应用场景 参考文章 前言 在听完厉风行老师<设计模式系列课程>中的建造者模式一节后顿时感觉有点头大,感觉它有点像工厂方 ...

  7. Java 设计模式 -- 建造者模式

    建造者模式 建造者模式就是一步一步的创建一个复杂的对象,而且允许用户指定复杂对象的类型和内容. Builder 类是一个抽象类,用于定义一些创建子部件的方法,Builder类中应该还有一个 getRe ...

  8. JAVA设计模式 - 建造者模式

    建造者模式 , 又称为生成器模式 . 是创建型模式之一 . 与工厂方法模式和抽象工厂模式不同 , 这两种模式的目的是为了实现多态性 , 而建造者模式的目的则是为了将对象的构建与展示分离 .       ...

  9. 【面试高频】Java设计模式-建造者模式

    ⭐️写在前面 这里是温文艾尔的学习之路

最新文章

  1. Spring 的 BeanFactory 和 FactoryBean 傻傻分不清?
  2. 观念什么意思_观念真不是凭空出现的,也不是单一的,观念来自环境并且不止一种...
  3. 不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接。中断与此服务器或共享资源的连接,然后在试一次...
  4. Java经典面试题整理及答案详解(二)
  5. python基本数据类型包括哪些_python入门3——基本数据类型
  6. Linux shell multifile content replace with sed
  7. 基于JAVA+SpringBoot+Mybatis+MYSQL的文档管理系统
  8. 算法不会,尚能饭否之排序——折半插入排序(Binary Insert Sort)
  9. Java高级进阶学习资料!Java虚拟机的垃圾回收机制
  10. Android 多线程之阻塞队列
  11. ThreadPoolExecutor运转机制详解
  12. SparrowRecSys电影推荐系统项目(一)
  13. 16 Cesium—矢量数据
  14. 2017最新xcode打包APP详细图文
  15. CI、CD、Pipeline 概念
  16. 糗事百科李威: 如何基于数据构建推荐系统,助力精细化运营?
  17. 如何第一次办理港澳通行证、护照、台湾通行证
  18. 银联商务管理层换血:光大控股后撤,曾因违规被罚没3267万元
  19. 案例21:Java农产品供求信息系统设计与实现开题报告
  20. Python之 【模型建立和测试-模型测试模板】

热门文章

  1. 四足机器人单腿逆运动学解-几何方法
  2. 2020.9.16hive基础
  3. VBA编程——范例一
  4. 3dmax软件怎么保存低版本的模型
  5. 用计算机写试卷反思,“我的试卷,我分析,我反思1——学生写试卷分析及反思的收获...
  6. WWDC20 CoreImage 专题
  7. 中文puppy linux7.5,Puppy Linux 7.5发布,支持UEFI启动的
  8. 2021年国网计算机考试难吗,2021想要通过国家电网招聘考试到底有多难?
  9. 【进制】计算机底层是如何计算2+3的?
  10. 喵呜的旅行(费用流)