建造者模式详解

2023-05-16

建造者模式

建造者模式(Bulider Pattern)是将一个复杂对象的构建过程与它的实现表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。使用创建者模式对于用户而言只需要制定需要建造的类就可以获得对象,建造过程及细节不需要了解。
建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不一定固定。如果一个对象有非常复杂的内部结构(很多属性),可以将复杂对象的创建和使用进行分离。
建造者模式的设计主要有四个角色:
1、产品(Product):要创建的产品对象

@Data
public class Product{
    private String id;
    private String name;
    
    @Override
    public String toString() {
        return "CourseBuilder{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                '}';
    }
}

2、建造者抽象(Builder):建造者的抽象类,规范产品对象的各个组成部分的建造,一般由子类实现具体的建造过程。

public interface Builder{
    void build();
}

3、建造者(ConreteBuilder):具体的Builder类,根据不同的业务逻辑,具体化对象的各个组成部分的创建。

public class ConreteBuilder implments Builder{
    private Product product = new Product();
    public CourseBuilder addName(String name) {
        course.setName(name);
        return this;
    }

    public CourseBuilder addId(String id) {
        course.setId(id);
        return this;
    }
    @Override
    public Course build() {
        return this.course;
    }
}

4、调用者(Diretor):调用具体的建造者,来创建对象的各个部分,在调用者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

public class Test {
    public static void main(String[] args) {
        CourseBuilder builder = new CourseBuilder();

        builder.addName("设计模式");
               .addPPT("12314551123");

        System.out.println(builder.build());

    }
}

建造者模式的应用场景

建造者模式适用于一个具有较多的零件的复杂产品的创建过程,由于需求的变化,组成这个复杂产品的各个零件经常猛烈变化,但是他们的组合方式却相对稳定。
建造者模式适用于以下的几种场景:
1、相同的方法,不同的执行顺序,产生不用的结果时
2、多个部件或者零件,都可以装配到一个对象中,但是产生的结果又不相同
3、产品非常复杂,或者产品类中的调用顺序不用产生不同的作用
4、当时初始化一个对象特别复杂,参数多,而且很多参数都具有默认值时

建造者模式的基本写法

我们还是以课程为例,一个完整的课程需要由PPT课件、回放视频、课堂笔记、课后作业组成,但是这些内容的设置顺序可以随意搭配调整,我们用建造者模式来带入了解一下。首先我们需要创建一个需要构造的产品类Course:

public class Course {

    private String name;
    private String ppt;
    private String video;
    private String note;

    private String homework;

    @Override
    public String toString() {
        return "CourseBuilder{" +
                "name='" + name + '\'' +
                ", ppt='" + ppt + '\'' +
                ", video='" + video + '\'' +
                ", note='" + note + '\'' +
                ", homework='" + homework + '\'' +
                '}';
    }
}

然后创建者建造类CourseBuilder,将复杂的构造过程封装起来,构造步骤由用户决定:

public class CourseBuilder{

    private Course course = new Course();

    public void addName(String name) {
        course.setName(name);
    }
    
    public void addPPT(String ppt) {
        course.setPpt(ppt);
    }
    
    public void addVideo(String video) {
        course.setVideo(video);
    }
    
    public void addNote(String note) {
        course.setNote(note);
    }
    
    public void addHomework(String homework) {
        course.setHomework(homework);
    }
    
    public Course build() {
        return course;
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        CourseBuilder builder = new CourseBuilder();

        builder.addName("设计模式");
        builder.addPPT("【PPT课件】");
        builder.addVideo("【回放视频】");
        builder.addNote("【课堂笔记】");
        builder.addHomework("【课后作业】");

        System.out.println(builder.build());

    }
}

建造者模式的链式写法

在平时的应用中,建造者模式通常是采用链式编程的方式构造对象,下面我们来看一下掩饰代码,修改CourseBuilder类,将Course变为CourseBuilder的内部类:

@Data
public class Course {

        private String name;
        private String ppt;
        private String video;
        private String note;

        private String homework;

        @Override
        public String toString() {
            return "CourseBuilder{" +
                    "name='" + name + '\'' +
                    ", ppt='" + ppt + '\'' +
                    ", video='" + video + '\'' +
                    ", note='" + note + '\'' +
                    ", homework='" + homework + '\'' +
                    '}';
        }
}

然后,将构造步骤添加进去,每完成一个步骤,都返回this:

public class CourseBuilder {
    private Course course = new Course();

    public CourseBuilder addName(String name) {
        course.setName(name);
        return this;
    }

    public CourseBuilder addPPT(String ppt) {
        course.setPpt(ppt);
        return this;
    }

    public CourseBuilder addVideo(String video) {
        course.setVideo(video);
        return this;
    }

    public CourseBuilder addNote(String note) {
        course.setNote(note);
        return this;
    }

    public CourseBuilder addHomework(String homework) {
        course.setHomework(homework);
        return this;
    }

    public Course build() {
        return this.course;
    }
}

客户端使用:

public class Test {
    public static void main(String[] args) {
        CourseBuilder builder = new CourseBuilder()
                    .addName("设计模式")
                    .addPPT("【PPT课件】")
                    .addVideo("【回放视频】")
                    .addNote("【课堂笔记】")
                    .addHomework("【课后作业】");

        System.out.println(builder.build());
    }
}

建造者模式在源码中的体现

下面来看建造者模式在哪些源码中有应用呢?首先来看JDK的StringBuilder,它提供append()方法,给我们开放构建步骤,最后调用toString()方法就可以获得一个构建好的完整的字符串,源码如下:

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable,CharSequence{
    ...
    public StringBuilder append(String str){
        super.append(str);
        return this;
    }
    ...
}

在MyBatis中也有体现,比如CacheBuilder类。
同样在Mybatis中,比如SqlSessionFactoryBuilder通过调用builder()方法获得的是一个SqlSessionFactory类。
当然,在Spring中自然也少不了,比如BeanDefinitionBuilder通过调用getBeanDefinition()方法获得一个BeanDefinition对象

建造者模式的优缺点

建造者模式的优点:
1、封装性好,创建和使用分离;
2、扩展性好,建造类之间独立、一定程度上解耦。
建造者模式的缺点:
1、产生多余的Builder对象;
2、产品内部发生变化,建造者都要修改,成本较大。

建造者模式和工厂模式的区别

通过前面的学习,我们已经了解建造者模式,那么它和工厂模式有什么区别呢?
1、建造者模式更加注重方法的调用顺序,工厂模式注重于创建对象。
2、创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。
3、关注点不一样,工厂模式只需要把对象创建出来就行了,而建造者模式不仅要创建出这个对象,还要知道这个对象由哪些部分组成。
4、建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

建造者模式详解 的相关文章

随机推荐

  • mysql-plus 字段验证策略fieldStrategy

    ignored 不管有没有有设置属性 xff0c 所有的字段都会设置到insert语句中 xff0c 如果没设置值 xff0c 全为null xff0c 这种在update 操作中会有风险 xff0c 把有值的更新为null not nul
  • Navicat 12 for MySQL最新版激活(注册机)

    整个过程在断网环境下 安装包也用刚下载的 转 https blog csdn net zhangli0910 article details 83785147 最新版注册机 43 Navicat下载 xff1a 链接 xff1a https
  • C_INCLUDES must be under the source or output directories

    Android项目N版本切到O版本 xff0c 同一个模块去mm xff0c 报C INCLUDES must be under the source or output directories错误 后来才找到原因 xff0c 是因为该模块
  • “MobaXterm X11 proxy: Unsupported authorisation protocol”解决方法

    服务器无法显示GUI图片问题 在解决这个问题的时候 xff0c 可能很多人都搜到了用sudo的方法 xff0c 但是在我们没有管理权限的情况下 xff0c 这个问题也是能解决的 报错信息 我的报错信息 xff1a MobaXterm X11
  • Linux 并发与竞争

    Linux是一个多任务操作系统 xff0c 肯定会存在多个任务共同操作同一段内存或者设备的情况 xff0c 多个任务甚至中断都能访问的资源叫做共享资源 xff0c 就和共享单车一样 在驱动开发中要注意对 共享资源的保护 xff0c 也就是要
  • linux man手册和设置中文版man手册

    http man he net linux 设置中文版man手册
  • win10宽带连接断网自动重连

    文章目录 1 断开网络连接 xff0c 重命名网络连接2 bat代码 xff1a 检测到断线自动重连3 设置开机自动执行3 1 方式一 xff1a 任务计划程序3 2 方式二 xff1a 用vbs代码开机运行bat 1 断开网络连接 xff
  • ubuntu20环境下使用DevStack安装Openstack-Wallaby(单节点、多节点)

    文章目录 一 单节点部署1 环境准备1 1 镜像源1 2 pip源1 3 安装依赖包 2 OpenStack安装 wallaby2 1 添加 96 stack 96 用户2 2 设置代理2 3 下载devstack xff0c 使用 96
  • 【操作系统】页面置换算法

    页面置换算法 在进程运行过程中 xff0c 若需要访问的物理块不在内存中 xff0c 就需要通过一定的方式来将页面载入内存 xff0c 而此时内存很可能已无空闲空间 xff0c 因此就需要一定的算法来选择内存中要被置换的页面 xff0c 这
  • 前端 好看实用的颜色大全(16进制)

  • 解决linux写入ntfs盘时报错:只读文件系统

    2018 10 28 更新 可能因为在挂载wimdows盘后 xff0c 强制关机造成的 xff0c 可使用 sudo ntfsfix dev 来修复 其中 xff0c 为具体哪个盘 xff0c 例如sudo ntfsfix dev sda
  • 【计算机网络】TCP IP通信处理过程

    1 数据包首部 每个分层中都会对所发送的数据附加一个首部 xff0c 其中包含了该层必要的信息 xff0c 如发送端地址 接收端地址以及协议等相关信息 2 发送数据包 1 xff09 应用程序处理 进行编码处理 xff08 相当于表示层功能
  • 【高性能定时器】 时间轮

    时间轮 简述 顾名思义 xff0c 时间轮就像一个轮子 xff0c 在转动的时候外界会指向轮子不同的区域 xff0c 该区域就可以被使用 因此只要将不同时间的定时器按照一定的方法散列到时间轮的不同槽 xff08 即时间轮划分的区域 xff0
  • 系统调用中断(EINTR)与SIGCHLD信号的处理

    一 被中断的系统调用 EINTR 的理解 1 慢系统调用是 xff1f 2 慢系统调用的类别3 EINTR产生的原因5 一般处理方法 二 SIGCHLD信号的处理 1 SIGCHLD信号的产生2 SIGCHLD信号的处理3 不处理SIGCH
  • 定时器与超时的设置

    一 相关时间函数 1 gettimeofday 2 time 3 clock 二 间隔定时器 1 setitimerval 2 getitimerval 3 实时定时器的使用 三 为阻塞操作设置超时 1 alarm 2 给read 设置读超
  • 解决tomcat启动时,端口被占用问题

    有时候我们启动tomcat的时候 xff0c 会提示端口被占用 xff0c 我们可以用下面的方法解决这个问题 1 进入cmd 2 输入netstat ano findstr 8080 xff08 注 xff1a 8080为被占用的端口名 x
  • Maven实战(六)--- dependencies与dependencyManagement的区别

    在上一个项目中遇到一些 jar 包冲突的问题 xff0c 之后还有很多人分不清楚 dependencies 与 dependencyManagement 的区别 xff0c 本篇文章将这些区别总结下来 1 DepencyManagement
  • VSFTP服务器使用retrieveFileStream返回null的问题

    VSFTP服务器使用retrieveFileStream返回null的问题 最近在使用vsftp在文件存储服务 xff0c 发现使用retrieveFileStream获取文件流的时候 xff0c 怎么获取都是空的 xff0c 网上有说返回
  • Android常用的一些make命令

    1 make jX X表示数字 xff0c 这个命令将编译Android系统并生成镜像 xff0c XX表示可以使用到的CPU核数 xff0c 这在配置好的电脑上特别有用 xff0c 公司的16核ubuntu服务器执行make j16只要不
  • 建造者模式详解

    建造者模式 建造者模式 xff08 Bulider Pattern xff09 是将一个复杂对象的构建过程与它的实现表示分离 xff0c 使得同样的构建过程可以创建不同的表示 xff0c 属于创建型模式 使用创建者模式对于用户而言只需要制定