建造者模式(八)

news2025/2/14 3:45:11

不管怎么样,都要继续充满着希望

上一章简单介绍了原型模式(七), 如果没有看过, 请观看上一章

一. 建造者模式

引用 菜鸟教程里面的建造者模式介绍: https://www.runoob.com/design-pattern/builder-pattern.html

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

一.一 介绍

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

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

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

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

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

应用实例

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

2、JAVA 中的 StringBuilder。

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

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

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

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

组成角色具体关系作用
产品(Product)House具体生产器要构造的复杂对象具体生产器要构造的复杂对象
具体生产器(ConcreteBuilder)SimpleHouseBuilder,HightHouseBuilder生产各个组件实现Builder接口的类,具体生成器将实现Builder接口所定义的方法
抽象生成器(Bulider)HouseBuilder定义构造步骤除了为创建一个Product对象的各个组件定义了若干个方法之外,还要定义返回Product对象的方法
指挥者(Director)HouseDirector按照步骤组装部件,并返回Product按照步骤组装部件,并返回Product

image-20230614110041817

二. 实现

如 定义一个盖房子的操作

二.一 不使用建造者模式

二.一.一 定义抽象类

定义一个抽象类:

public abstract class AbstractHouse {
    protected abstract void buildBasic();
    protected abstract void buildWalls();
    protected abstract void buildRoofed();

    public void build () {
        buildBasic();
        buildWalls();
        buildRoofed();
    }
}

二.一.二 子类实现

@Slf4j
public class SimpleHouse extends AbstractHouse{
    @Override
    protected void buildBasic() {
        log.info("简单楼打地基");
    }

    @Override
    protected void buildWalls() {
        log.info("简单楼砌墙壁");
    }

    @Override
    protected void buildRoofed() {
        log.info("简单楼地板");
    }
}
@Slf4j
public class HightHouse extends AbstractHouse{

    @Override
    protected void buildBasic() {
        log.info("高楼打地基");
    }

    @Override
    protected void buildWalls() {
        log.info("高楼砌墙壁");
    }

    @Override
    protected void buildRoofed() {
        log.info("高楼地板");
    }
}

二.一.三 测试方法

 @Test
    public void oneTest() {
        AbstractHouse simpleHouse = new SimpleHouse();
        simpleHouse.build();

        AbstractHouse hightHouse  = new HightHouse();
        hightHouse.build();
    }

image-20230614111038377

这种方式是不符合设计原则的.

二.二 建造者模式

二.二.一 定义产品 Product

@Data
public class House {
    private String basic;
    private String wall;
    private String roofed;
}

二.二.二 抽象生成器 Builder

一般只需要一个方法 build()

public abstract class HouseBuilder {

    protected House house = new House();

    protected abstract void buildBasic();
    protected abstract void buildWalls();
    protected abstract void buildRoofed();

    public House build() {
        buildBasic();
        buildWalls();
        buildRoofed();
        return house;
    }
    /**
     一个其他的类型操作,类似于不同的套餐
     */
    public House noRoofBuild () {
        buildBasic();
        buildWalls();
        return house;
    }
}

二.二.三 具体生产器 ConcreteBuilder

public class SimpleHouseBuilder extends HouseBuilder{

    @Override
    protected void buildBasic() {
        house.setBasic("地基10");
    }

    @Override
    protected void buildWalls() {
        house.setWall("砌墙2");
    }

    @Override
    protected void buildRoofed() {
        house.setRoofed("地板2");
    }
}
public class HightHouseBuilder extends HouseBuilder{

    @Override
    protected void buildBasic() {
        house.setBasic("地基100");
    }

    @Override
    protected void buildWalls() {
        house.setWall("砌墙20");
    }

    @Override
    protected void buildRoofed() {
        house.setRoofed("地板20");
    }
}

二.二.四 指挥者 Director

public class HouseDirector {
    HouseBuilder houseBuilder = null;

    public HouseDirector (HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    public void setHouseBuilder(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    public House build () {
        return this.houseBuilder.build();
    }

    public House noRoofBuild () {
        return this.houseBuilder.noRoofBuild();
    }
}

二.二.五 测试使用

    @Test
    public void twoTest() {
        HouseDirector houseDirector = new HouseDirector(new HightHouseBuilder());
        House house = houseDirector.build();
        log.info(">>> 打印高信息: {}", house);

        houseDirector.setHouseBuilder(new SimpleHouseBuilder());

        House noRoofHouse = houseDirector.noRoofBuild();
        log.info(">>> 打印低信息: {}", noRoofHouse);
        
        House house2 = houseDirector.build();
        log.info(">>> 打印低信息: {}", house2);
    }

image-20230614111702033

三. 普通实体类的建造者

如,我们定义一个 Student 类

注意, @Builder 注解

@Data
@Builder
public class Student {
    private Integer id;
    private String name;
    private String sex;
}

我们在使用的时候,是这样使用的, 是一个建造者

@Test
    public void threeTest() {
        Student student = Student.builder().id(1).name("张三").sex("男").build();
        log.info("学生信息: {}", student);
    }

image-20230614111857514

源代码会动态编译成:

public class Student {
    private Integer id;
    private String name;
    private String sex;

    Student(Integer id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    public static Student.StudentBuilder builder() {
        return new Student.StudentBuilder();
    }

    public static class StudentBuilder {
        private Integer id;
        private String name;
        private String sex;

        StudentBuilder() {
        }

        public Student.StudentBuilder id(Integer id) {
            this.id = id;
            return this;
        }

        public Student.StudentBuilder name(String name) {
            this.name = name;
            return this;
        }

        public Student.StudentBuilder sex(String sex) {
            this.sex = sex;
            return this;
        }

        public Student build() {
            return new Student(this.id, this.name, this.sex);
        }

        public String toString() {
            return "Student.StudentBuilder(id=" + this.id + ", name=" + this.name + ", sex=" + this.sex + ")";
        }
    }
}

本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Builder


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业自动化解决方案 - RPA

下方查看历史精选文章 重磅发布 - 自动化框架基础指南pdfv1.1大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 什么是RPA? RPA指的是机器人流…

手势识别系统Python,基于卷积神经网络算法

一、介绍 手势识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,…

Elasticsearch:数据摄取中的使用指南

数据摄取是利用 Elasticsearch 的全部潜力进行高效搜索和分析的关键步骤。 在本文中,我们将探讨几个常用的基本实践,以确保将无缝且有效的数据摄取到 Elasticsearch 中。 通过遵循这些指南,你可以优化数据摄取流程,并在你的部署中…

还在为618电商推送方案烦恼?我们帮你做好了!

618是每年重要的电商大促活动,热度高流量大,是电商App吸引新用户,提高用户转化率(购买率)的最好时机。对电商App运营来说,消息推送是不可忽略的流量来源之一,适当的消息推送可以召回用户,提高用户复购率。如…

Tigers Global Logistics EDI 需求及SaaS解决方案

Tigers Global Logistics 是一家国际物流公司,总部位于香港,成立于1998年。该公司提供全球物流服务,包括仓储、运输、海关通关、电商物流等。Tigers Global Logistics 在全球范围内拥有超过70个仓库和物流中心,并在美国、欧洲、亚…

Spring MVC入门笔记

Spring MVC基础知识 1. 创建web应用 新建Maven项目 点击File -> Project Structure -> Facets -> 号 -> Web 修改文件描述符路径为硬盘:\项目名\src\main\存储页面的文件夹(如:webapp)\WEB-INF\web.xml 修改Web页面路径为硬盘…

领域建模之数据模型设计方法论

本文通过实际业务需求场景建模案例,为读者提供一种业务模型向数据模型设计的方法论,用于指导实际开发中如何进行业务模型向数据模型转化抽象,并对设计的数据模型可用性、扩展性提供了建议性思考。通过文章,读者可以收获到业务模型…

打造高效采购系统,提升企业采购效率

随着市场竞争的日益激烈,企业采购效率的重要性越来越凸显。采购系统作为企业采购的核心环节,是提升采购效率的关键。因此,打造高效采购系统是企业发展的必要条件。本文将围绕打造高效采购系统,提升企业采购效率展开讨论。 一、采购…

JavaWeb小项目——【源码】使用Vue+axios+Servlet+Lombok+JDBC+MySQL技术栈实现云笔记管理系统案例的开发

目录 引出小项目要求固定的东西1.pom.xml文件配置 web.xml文件配置2.util里面JDBC的DBUtils 字符串工具StringUtils3.entity里面的PageInfo分页实体类ResData响应标准格式4.filter里面的编码CharacterEncodingFilter和权限LoginAuthorFilter5.前端固定的js包和bootstrap包 小…

深入剖析mmap原理 - 从三个关键问题说起

作者:招财二师兄 链接:https://www.jianshu.com/p/eece39beee20 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 对于mmap,您是否能从原理上解析以下三个问题: 1&#…

CentOS阿里镜像源

阿里CentOS镜像源位置:http://mirrors.aliyun.com/centos/?spma2c6h.25603864.0.0.50d03715CS95s4 CentOS下载最小位置: https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/?spma2c6h.25603864.0.0.5e38f5advNCSXC 如图:

用敏捷工具Leangoo领歌做敏捷需求管理

传统的瀑布工作模式使用详细的需求说明书来表达需求,需求人员负责做需求调研,根据调研情况编制详细的需求说明书,进行需求评审,评审之后签字确认交给研发团队设计开发。在这样的环境下,需求文档是信息传递的主体&#…

vue H5项目如何在PC端时居中展示,而不全屏拉伸

目录 1、场景再现:在PC端时 H5项目布局被拉伸2、代码实现3、最终效果图4、疑惑 1、场景再现:在PC端时 H5项目布局被拉伸 2、代码实现 在App.vue中的写入,vue2 的在mounted中写入,vue3的写在onMounted写入。 逻辑讲解&#xff1a…

Linux之进程掩码 umask

目录 Linux之进程掩码 umask 最大权限 umask unmask作用 语法格式 参数及作用 umask存放位置 案例 示例1 --- 在shell进程中创建文件 示例2 --- 修改shell umask值(临时) 示例3 --- 修改shell umask值(永久) 示例4 ---…

机器人项目创新课题汇总提示

创新课题推荐自己思考并给出,如下案例仅供参考: 不想看,不愿意做,就遵循自己内心想法,做自己喜欢的事情吧。 题目和描述: 自动导航机器人:设计一种能够自主导航的机器人,可以在不需…

实验篇(7.2) 14. 站对站安全隧道 - 走对方宽带上网(FortiGate-IPsec) ❀ 远程访问

【简介】前面实验已经知道,FortiClient客户端拨号到远端防火墙,包括上网流量等所有流量都可以通过隧道到达远端防火墙,并从对方宽带上网。那么两台防火墙之间连接的安全隧道,可以实现这个功能吗? 实验要求与环境 OldMe…

BTree和B+Tree详解

BTree和BTree详解 B树索引是B树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B树中的B代表平衡(balance),而不是二叉(binary),因为B树是从最早的平衡二叉树演化而来的。在讲B树之前必须先了解二叉查找树、平衡二叉树(…

群晖nas(DS423+)和百度云盘互相自动备份

群晖nas提供了云同步功能,使用该功能,可以将百度云盘和群晖nas设置成互为备份,这样我们nas上的的重要数据就有多了一层保护。 通过设置,可以将nas上的某个目录同步到百度云盘的一个目录中,同步的方向可以自行定义&…

springmvc整合thymeleaf

概述 Thymeleaf提供了一组Spring集成,使您可以将其用作Spring MVC应用程序中JSP的全功能替代品。 这些集成将使您能够: Controller像使用JSP一样,将Spring MVC 对象中的映射方法转发到Thymeleaf管理的模板。在模板中使用Spring表达式语言&…

win10中部署个人邮件服务器hMailServer

一、安装邮件服务器hMailServer hMailServer是一个免费的开源电子邮件服务器,适用于Microsoft Windows,本次实践以Windows10为例。hMailServer支持常见的电子邮件协议(IMAP、SMTP 和 POP3),并且可以轻松地与许多现有的 Web 邮件系统集成。它具有灵活的垃圾邮件保护,可以附…