java 设计模式--创建者模式

参考:Java常见设计模式总结

概念

概念理解一:将复杂对象的创建过程分解在不同的方法中,不同的创建过程组装成不同对象。对象的创建与产品本身分离开,使得对象的创建过程更加清晰。例如:旅游套餐售卖场景。
一个套餐大概会由机票、车票、酒店、景点门票组成。
套餐A: 机票1 + 酒店1 + 景点门票1
套餐B: 车票1 + 景点门票2
套餐C: 机票1 + 酒店1
等等
概念理解二:如果对象的构造的入参十分复杂时,构造对象需要转为链式写法时
第三方库举例:
1、由于产品的构造函数参数太多或者组合方式太多
Mybaitis 和 SqlSessionFactoryBuilder
2、将 set 方法转成链式写法
StringBuilder,StringBuffer.append()方法

抽象建造者 Builder:相当于建筑蓝图,声明了创建 Product 对象的各个部件指定的抽象接口。
具体建造者 ConcreteBuilder:实现Builder抽象接口,构建和装配各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
指挥者 Director:构建一个使用 Builder 接口的对象。主要有两个作用,一是隔离用户与对象的生产过程,二是负责控制产品对象的生产过程。
产品角色 Product:被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

抽象构造者

@Data
public abstract class Builder {
    Package pack = new Package();
    public abstract void buildAirTicket();
    public abstract void buildHotel();
    public abstract void buildTripTicket();
    public abstract void buildCarTicket();

    public Package getPack(){
        return pack;
    }
}

套餐A具体的构造者 PackageAConcreteBuilder

@Data
public class PackageAConcreteBuilder extends Builder {
//    套餐A: 机票1 + 酒店1 + 景点门票1
    @Override
    public void buildAirTicket() {
        AirTicket airTicket1 = new AirTicket(1000, 999, "机票1", "0001", 200);
        pack.setAirTicket(airTicket1);
    }

    @Override
    public void buildHotel() {
        Hotel hotel1 = new Hotel(300, 999, "酒店1", 2);
        pack.setHotel(hotel1);
    }

    @Override
    public void buildTripTicket() {
        TripTicket tripTicket1 = new TripTicket(50, 9999, "景点门票1");
        pack.setTripTicket(tripTicket1);
    }

    @Override
    public void buildCarTicket() {
        return;
    }

    @Override
    public Package getPack() {
        return super.getPack();
    }
}

套餐B具体的构造者 PackageBConcreteBuilder

@Data
public class PackageBConcreteBuilder extends Builder{
//    套餐B: 车票1 + 景点门票2
    @Override
    public void buildAirTicket() {

    }

    @Override
    public void buildHotel() {

    }

    @Override
    public void buildTripTicket() {
        TripTicket tripTicket2 = new TripTicket(30, 9999, "景点门票2");
        pack.setTripTicket(tripTicket2);
    }

    @Override
    public void buildCarTicket() {
        CarTicket carTicket1 = new CarTicket(50, 9999, "车票1","0876");
        pack.setCarTicket(carTicket1);
    }

    @Override
    public Package getPack() {
        return super.getPack();
    }
}

套餐模型对象类 Package 相当于图中的 Product

@Data
public class Package {
    AirTicket airTicket;
    Hotel hotel;
    TripTicket tripTicket;
    CarTicket carTicket;

    public Package() {
    }

    public Package(AirTicket airTicket, Hotel hotel, TripTicket tripTicket, CarTicket carTicket) {
        this.airTicket = airTicket;
        this.hotel = hotel;
        this.tripTicket = tripTicket;
        this.carTicket = carTicket;
    }
}

构造者

@Data
public class SystemDirector {
    private Builder builder;

    public void setBuilder(Builder builder){
        this.builder = builder;
    }
    public Package ConcreteBuilder(){
        builder.buildAirTicket();
        builder.buildHotel();
        builder.buildCarTicket();
        builder.buildTripTicket();

       return builder.getPack();
    }
}

如何使用

public static void main(String[] args){
        SystemDirector systemDirector = new SystemDirector(); // 指挥者
        PackageAConcreteBuilder packageABuilder = new PackageAConcreteBuilder();
        PackageBConcreteBuilder packageBBuilder = new PackageBConcreteBuilder();

        systemDirector.setBuilder(packageABuilder);// 指挥操作套餐A
        Package packageA = systemDirector.ConcreteBuilder();//套餐A的具体构造者创造对象     log.info("packageA,airTicket:{},hotel:{},tripTicket:{}",packageA.airTicket.getName(),
                packageA.hotel.getName(),packageA.tripTicket.getName());

        systemDirector.setBuilder(packageBBuilder);// 指挥操作套餐B
        Package packageB = systemDirector.ConcreteBuilder();//套餐B的具体构造者创造对象
        log.info("packageB,carTicket:{},tripTicket:{}",packageB.carTicket.getName(), packageB.tripTicket.getName());
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flutter Android 自定义输出路径 apk名称

默认 Flutter flutter build apk, 是默认的名字 默认的路径,直接修改输出路径 会造成 打包可以,直接运行 会提示找不到 apk 文件; 这里的解决思路是:打包完成后 拷贝目标路径的 APK 到自定义的路径,这样既可以正常打…

Windows软件架构概念

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来聊聊Windows软件架构的概念。 Shaw和Garlan在他们划时代的著作中以如下方式讨论了软件的体系结构:从第一个程序被划分成模块开始,软件系统就有了体系结构。现在&#xff0c…

分布式系统消息通信技术:MOM与RPC

一、中间件 什么是中间件 中间件(Middleware)是处于操作系统和应用程序之间的软件,也有人认为它应该属于操作系统中的一部分。人们在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台…

剑指 Offer 55 - I. 二叉树的深度 / LeetCode 104. 二叉树的最大深度(二叉树后序遍历,回溯传递值)

题目: 链接:剑指 Offer 55 - I. 二叉树的深度;LeetCode 104. 二叉树的最大深度 难度:简单 输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条…

【框架源码】Spring源码解析之BeanDefinition加载流程解析

观看本文之前,我们先思考一个问题,Spring是如何描述Bean对象的? Spring是根据BeanDefinition来创建Bean对象,BeanDefinition就是Spring中表示Bean定义。BeanDefinition用来存储Bean的相关信息,主要包括:Be…

智能文档图像处理技术应用与实践

写在前面智能文档处理面临的技术难题智能文档处理的研究领域● 文档图像分析与预处理● 手写板反光擦除● 版面分析与文档还原 写在最后 写在前面 VALSE 2023 无锡视觉与学习青年学者研讨会近期在无锡国际博览中心举办,由江南大学和无锡新吴区联合承办。本次会议旨…

企业级ChatGPT开发的三大核心内幕及案例实战(三)

企业级ChatGPT开发的三大核心内幕及案例实战(三) 2.3 Notion 问答对话AI案例演示及源码分析 Gavin老师:NLP_Matrix_Space 如图2-2所示,我们先看一下Notion 问答对话AI案例的效果。你问一个问题,它会进行回答,然后它会告诉你,信息来源在什么地方,要看具体的信息,可以…

生产者与消费者问题

本篇文章我们使用C探讨一下生产者与消费者问题. 1. 多线程的引入 我们学习了操作系统, 知道了进程和线程的概念, 但是如果不进行代码实战的话, 会很难理解它们. 特别是编程的初学者(比如我), 在了解了进程和线程后通常会感到疑惑: 多线程怎么用? 为啥我平时写代码没有使用到…

TCP协议的相关特性

目录 TCP特点概要 TCP协议段格式 TCP原理 确认应答 超时重传 连接管理(三次握手,四次挥手) 三次握手 四次挥手 流水线传输 滑动窗口 滑动窗口ACK丢失 滑动窗口数据报丢失 流量控制 拥塞控制 延迟应答 停止等待协议 回退N帧协议 面向字节流 缓冲区 粘包问题 TCP异常 &…

Nginx Rewrite的应用

目录 一、Nginx Rewrite 二、Rewrite的功能 1.Rewrite 跳转场景 2.Rewrite 跳转实现 3.Rewrite 实际场景 4.Rewrite 正则表达式 5.Rewrite 命令/语法格式 6.location 分类 7.location 优先级 8.Rewrite和location比较 9.根据以上了解,小案例来操…

python实现Canny算子边缘检测算法

边缘检测是一种将图片中关键信息表现出来的一种图片技术,它的结果并不是字面意思上的获取图片边缘,而是将图片有用的信息勾勒出来,类似素描的结果,但是已经去掉了很多信息。如下所示,一张原始的图片是这样的&#xff1…

自学黑客/网络安全工具软件大全100套

黑客工具软件大全100套 1 Nessus:最好的UNIX漏洞扫描工具 Nessus 是最好的免费网络漏洞扫描器,它可以运行于几乎所有的UNIX平台之上。它不止永久升级,还免费提供多达11000种插件(但需要注册并接受EULA-acceptance–终端用户授权…

Redis7【④ Redis 发布 订阅】

Redis发布和订阅 本章了解即可,命令可以不用敲。 Redis 发布和订阅(Publish/Subscribe,简称 Pub/Sub)是一种消息传递模式,用于在 Redis 中实现消息的发布和订阅。 在 Redis 中,发布者(Publi…

高通9x07平台关于模块modem射频 RF MCFG生成MBN的总结

1.1: cefs(efs2.mbn)制作步骤:1.擦擦CEFS分区;2.导入HW_MBN,并激活;3.导入静态NV;4.生成CEFS; 1.2:激活hw_default mbn后,/policyman/目录下device_config.xml必需保留; 1.3&#xf…

Vision Transformer

论文名称: An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 一、Patch Embedding模块 class PatchEmbed(nn.Module): # 对应Patch Embedding模块def __init__(self, img_size224, patch_size16, in_c3, embed_dim768, norm_layerNone…

实现一个转盘随机选择器

实现效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><…

Midjourney如何用参考图/垫图来绘画图

大家都知道AI绘画工具每次生成的效果都是随机的&#xff0c;但是现在很多AI绘图工具都提供了利用参考图/垫图的方式出图&#xff0c;这样就可以让让AI画作生成自己想要的布局、场景、色彩等等。 国内的AI绘图工具一般都好操作&#xff0c;国外主流的Midjourney也可以添加参考图…

DataV图表-排名轮播表自定义

DataV图表-排名轮播表自定义数据大屏可视化 场景&#xff1a;需要计算根据分数不同柱子的颜色不同 低于60分变成为橙色柱子 一开始使用的是 dv-scroll-ranking-board 这个不可以自定义颜色和属性 我们可以更改 dv-scroll-board 样式来实现 排名轮播表 安装 data-view npm ins…

2023年最新互联网Java面试八股文出炉(附大厂P5-P8技术栈)

为什么感觉 Java 面试变难了&#xff1f; 几年前&#xff0c;你只需要简单的ssm框架&#xff0c;就能轻松找到一份Java的工作&#xff0c;但现在不一样了&#xff0c;随着涌入这个行业的人越来越多&#xff0c;同一个岗位需要筛选掉更多人&#xff0c;要求自然水涨船高&#x…

短视频------Adobe Photoshop 笔记总结

一、Adobe Photoshop 使用方式方法 ctrlc/v 复制 粘贴 ctrlx 剪切 ctrla 全选 ctrlz撤销 ctrls保存 ENTER 回车 换行 CTRL 调取定界框 CAPSLOCK 大写锁定 Esc 退出 Delete 删除 Backspace 退格 Ctrl shi alt 三个控制键 Shi 连选 ctrl 加选/减选 锁屏 WinL 打开运行命令窗口 …