Java设计模式之建造者模式的示例详解

 更新时间:2022年10月28日 16:54:14   作者:游坦之  
建造者模式,是一种对象构建模式 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。本文将通过示例讲解建造者模式,需要的可以参考一下

1 定义

建造者模式(Builder Patten):将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式用于一步一步创建一个复杂的对象,他允许用户只通过指定复杂对象的类型和内容进行构建,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式,根据翻译的不同,建造者模式又可称为生成器模式。

2 结构与角色

建造者模式包含4个角色

  • Builder:抽象建造者。为创建一个Product对象的各个部件指定的抽象接口。
  • ConcreteBuilder:具体建造者。实现抽象建造者Builder,构建和装配产品的各个部件。做具体建造工作,但却不为客户端所知。
  • Product:产品,被构建的复杂对象。具体建造者创建该产品的内部表示并定义它的装配过程。包含定义组成部件的类,包括将这些部件装配成最终的产品的接口。
  • Director:指挥者。构建一个使用抽象建造者Builder的对象。它与客户端打交道,将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给ConcreteBuilders。

3 例子

建造楼房的过程中,有专业人员绘制图纸,图纸中讲述干什么,工人根据图纸去具体实现要干的事情,包工头根据实际情况去处理图纸中方法的执行,调配工人以何种顺序完成图纸上的要求。虽然包工头和图纸对建造高楼很有帮助,但是高楼平地起,却是由工人们一砖一瓦的搭建起来。

以上的这个例子很形象的讲述建造者模式执行过程,其中图纸就对应Builder(提供方法,要干什么),工人就对应ConcreteBuilder(具体去干方法中规定的事情),包工头就对应Director(以何种顺序干,调配工人),高楼就对应Product。

3.1 代码

3.1.1 Builder类

Builder类只提供抽象的方法,类似于图纸,只是告诉你建造高楼你需要做什么。

// 抽象方法,要做什么:建设一个大楼需要做什么
public abstract class Builder {
    abstract void builderA();
    abstract void builderB();
    abstract void builderC();
    abstract void builderD();
    abstract Product getProduct();
}

3.1.2 Worker类

工人是具体实现Builder提出的需求,比如水泥、钢筋等等。工人类直接产生产品(new)

package demo01;
// 知道了要做什么,就得有人来具体实现
public class Worker extends Builder{
    private Product product;
    public Worker() {
        product = new Product();
    }
    @Override
    void builderA() {
        product.setBuildA("打地基");
        System.out.println("打地基");
    }
    @Override
    void builderB() {
        product.setBuildB("钢筋混凝土");
        System.out.println("钢筋混凝土");
    }
    @Override
    void builderC() {
        product.setBuildC("盖房子");
        System.out.println("盖房子");
    }
    @Override
    void builderD() {
        product.setBuildD("油漆、粉刷");
        System.out.println("油漆、粉刷");
    }
    Product getProduct()
    {
        return product;
    }
}

3.1.3 Product类

当产品的本身的属性一一被满足的时候,产品才会产生。

public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;
    public String getBuildA() {
        return buildA;
    }
    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }
    public String getBuildB() {
        return buildB;
    }
    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }
    public String getBuildC() {
        return buildC;
    }
    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }
    public String getBuildD() {
        return buildD;
    }
    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }
    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

3.1.4 Director类

包工头,安排工人怎么去做,比如今天下雨,不打水泥了,去抬钢筋,今天不下雨了,去打地基。

// 指挥的作用是,以什么样的顺序,完成产品的制作
public class Director {
    public Product getProduct(Builder builder){
        builder.builderA();
        builder.builderB();
        builder.builderC();
        builder.builderD();
        return builder.getProduct();
    }
}

3.1.5 Test测试类

public class Test01 {
    public static void main(String[] args) {
        Director director = new Director();
        Product product = director.getProduct(new Worker());
        System.out.println(product.toString());
    }
}

指挥者调整顺序可以得到不同的产品,或者不同的效果(虽然这个没体现出来)

4 不使用指挥者的例子

去餐厅吃饭,餐厅里一般有默认的套餐,或者自己(用户)点餐,点餐之后,服务员根据订单负责将食品端上来,然后你大快朵颐,享受美食带来的快感…

在这一场景里,就没有指挥者,指挥权到达了用户的手里。上面3中的场景,指挥权就不能到用户手里,你不能让人家掏钱还得让人家自己建(除非是老板)。

4.1 Builder类

public abstract class Builder {
    abstract Builder builderA(String msg);
    abstract Builder builderB(String msg);
    abstract Builder builderC(String msg);
    abstract Builder builderD(String msg);
    abstract Product getProduct();
}

4.2 Worker类

public class Worker extends Builder {
    private Product product;
    public Worker() {
         product = new Product();
    }
    Builder builderA(String msg) {
        product.setBuildA(msg);
        return this;
    }
    Builder builderB(String msg) {
        product.setBuildB(msg);
        return this;
    }
    Builder builderC(String msg) {
        product.setBuildC(msg);
        return this;
    }
    Builder builderD(String msg) {
        product.setBuildD(msg);
        return this;
    }
    Product getProduct() {
        return product;
    }
}

4.3 Product类

public class Product {
    private String buildA = "炸鸡";
    private String buildB = "汉堡";
    private String buildC = "可乐";
    private String buildD = "大蒜";
    public String getBuildA() {
        return buildA;
    }
    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }
    public String getBuildB() {
        return buildB;
    }
    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }
    public String getBuildC() {
        return buildC;
    }
    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }
    public String getBuildD() {
        return buildD;
    }
    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }
    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

4.4 Test类

public class Test {
    public static void main(String[] args) {
        Worker worker = new Worker();
        System.out.println(worker.builderA("全家桶")
                .getProduct());
    }
}

上面的代码例子中:Worker就相当于服务员,记录你点了什么菜,并生成账单(Product里的信息),反馈给用户产品。

5 适用场景

  • 需要生成的产品对象有复杂的内部结构(通常包含多个成员属性)
  • 需要生成的产品对象的属性相互依赖(需要指定顺序)
  • 产品对象的创建过程独立于创建该对象的类
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的类

6 优缺点

6.1 优点

  • 用户不需要知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 很方便的替换具体的建造者或者增加新的具体创建者
  • 符合开闭原则,可以更加精细的控制产品的创建过程

6.2 缺点

  • 适用范围收到限制,需要生成的产品对象具有较多共同点
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化。

到此这篇关于Java设计模式之建造者模式的示例详解的文章就介绍到这了,更多相关Java建造者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅析非对称加密在接口参数中的实现

    浅析非对称加密在接口参数中的实现

    接口层做数据加密应该算是老生常谈的一件事了,业界用的比较多的,不外乎是对称加密,非对称加密以及两者的结合。本文就来聊聊非对称加密在接口参数中的实现,希望对大家有所帮助
    2023-02-02
  • Java技巧分享之利用RxJava打造可观测数据RxLiveData

    Java技巧分享之利用RxJava打造可观测数据RxLiveData

    这篇文章主要来和大家分享一个Java技巧,那就是利用RxJava打造可观测数据RxLiveData,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-06-06
  • 简单了解JAVA构造方法

    简单了解JAVA构造方法

    构造方法作用就是对类进行初始化。 如果你没有定议任何构造方法的形式,程式会为你取一个不带任何参数的构造函数,那么你产生类的对像时只能用不带参数的方法.下面小编和大家来一起学习一下吧
    2019-06-06
  • java Volatile与Synchronized的区别

    java Volatile与Synchronized的区别

    这篇文章主要介绍了java Volatile与Synchronized的区别,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-12-12
  • SpringBoot整合Elasticsearch7.2.0的实现方法

    SpringBoot整合Elasticsearch7.2.0的实现方法

    这篇文章主要介绍了SpringBoot整合Elasticsearch7.2.0的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • springcloud初体验(真香)

    springcloud初体验(真香)

    这篇文章主要介绍了springcloud初体验(真香),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java实现链表的常见操作算法详解

    Java实现链表的常见操作算法详解

    这篇文章主要介绍了Java实现链表的常见操作算法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • java日常练习题,每天进步一点点(1)

    java日常练习题,每天进步一点点(1)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • SpringBoot整合Mybatis-Plus、Jwt实现登录token设置

    SpringBoot整合Mybatis-Plus、Jwt实现登录token设置

    Spring Boot整合Mybatis-plus实现登录常常需要使用JWT来生成用户的token并设置用户权限的拦截器,本文就来详细的介绍一下,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Spring中自定义拦截器的使用

    Spring中自定义拦截器的使用

    大家好,本篇文章主要讲的是Spring中自定义拦截器的使用,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02

最新评论