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

news2024/12/23 10:22:45

参考: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());
    }

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

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

相关文章

@DateTimeFormat与@JsonFormat不完全解析

目录 前言测试代码DateTimeFormat不加任何注解的情况普通请求JSON请求 JsonFormat普通请求JSON请求 其他方式(InitBinder)结论源码地址 前言 一直以来对DateTimeFormat与JsonFormat 比较模糊,容易搞忘,今天就做个笔记&#xff0c…

【MySQL 利器之 mysqldump】

文章目录 前言一、mysqldump二、环境三、使用步骤1.服务器与服务器间直接同步2.导出到sql文件3.sql文件导入 总结使用方式 1 服务器间直连方式同步:使用中间SQL 文件方式:datax: 前言 1.随着服务器环境改造,新旧数据库环境更换&a…

微流控压力控制器和微流控注射泵的性能比较

摘要:针对微流控技术中的压力和流量控制,本文介绍了目前常用的两类装置:注射泵和压力泵,重点介绍了这两种装置的性能特点,并对这两种压力控制装置进行了简要的分析对比。分析结论是压力泵将逐渐替代注射泵的应用&#…

Addressable CRC设置详解

设置 Asset Bundle的CRC设置中有三个选项: Disable; Enable,InClude Cached; Enable,Excludeing Cached; 修改后实际改的是这里的选项: Disable 设置为Disable,实际上是将BundledAssetGroupSchema类的UseAssetBundleCrc参数设…

软考:软件工程:软件设计,总体设计,详细设计,耦合内聚流程图,NS图,PAD图,判定树判定图。

软考:软件工程: 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是需要细心准备的 (1&#…

【吃透网络安全】2023软考网络管理员考点网络安全(二)网络攻击详解

涉及知识点 黑客的攻击手段介绍,常见的网络攻击,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 后面还有更多续篇希望大家能给个赞哈,这边提供个快捷入口! 第一节网络管理员考…

多版本管理node.js

多版本管理node.js 1. 安装2. 配置使用2.1 修改node源2.2 常用命令 在Windows 计算机上管理node.js的多个安装版本。 这是朋友推荐的,就是自己在升级node的时候给搞崩了, 不得不提升效率,于是发现了这个好工具,可以反过来理解&…

金蝶云星空RCE漏洞复现

0x01 产品简介 金蝶云星空是一款云端企业资源管理(ERP)软件,为企业提供财务管理、供应链管理以及业务流程管理等一体化解决方案。金蝶云星空聚焦多组织,多利润中心的大中型企业,以 “开放、标准、社交”三大特性为数字…

端午安康,节日送祝福

端午节是在中国农历的五月份,今年是(公历)6月22日,它是中国最古老的节日 之一,已经有两千多年的历史。The Duanwu or Dragon Boat Festival, is generally celebrated on the fifth month of the Chinese l…

(自定义包导包失败一万次的经验)ModuleNotFoundError: No module named ‘xxx‘

导自定义的包遇到的问题 首先我列一下我的目录结构 |-src|-__init__.py|-Dao|-insertData.py|-pojo|-DataBaseDao|-everyData我现在在我的insertData.py通过from src.pojo import DataBaseDao,everyData导包,在pycharm中可以正常运行,但是在控制台运行失败,提示 ModuleNotFo…

移植微雪例程-2.6寸双色墨水屏到ESP32IDF中

微雪官网:E-Paper ESP32 Driver Board - Waveshare Wiki 去微雪官网,把墨水屏的例程下下来。 我这个使用的是2.6寸的双色墨水屏。 下载下来之后,然后移植到IDF上面。 移植epd2in13bc-demo这个例程。将EPD_2in13bc.h这个头文件中的宽&#…

2022年广西壮族自治区第二届职业技能大赛“网络安全项目”比赛任务书

2022年广西壮族自治区第二届职业技能大赛 “网络安全项目”比赛任务书 一、竞赛时间 总计:12小时 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A A-1 登录安全加固 240分钟 350分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件监控…

算法程序设计 之 背包问题(5/8)

一、实验目的: 理解并掌握利用-动态规划算法与贪心算法求解不同背包问题。 实验内容 0-1背包问题给定n种物品和一个背包。物品i的重量是w[i],其价值为vi,背包的容量为C。问如何选择装入背包的物品,使得装入背包中物品的总价值最大…

CDH集群离线部署-6.3.1

1. 文件下载 CDH 安装使用到的相关文件:链接: https://pan.baidu.com/s/1xDQD1Sa8s47Qiu_EFYdhUA?pwd5mrt 提取码: 5mrt 2. 机器基础调整 所有机器都需要执行下面所有的步骤。 2.1. 准备机器 至少三台2核16G机器。 2.1.1. ECS 服务器 如果买的是 ECS 服务器&…

Apikit 自学日记:邀请成员一起协作

邀请成员一起协作 在 Apikit 中,所有的 API 接口都是以项目的方式进行管理,因此首先需要创建一个 API 管理项目。 除了创建 API 项目,还可以创建项目组来对项目进行分类或者设置统一的用户操作权限。 一、手动创建项目 进入 API 研发管理项…

有趣的笔试题——贪吃蛇游戏(确定不进来看看?)

原题 贪吃蛇游戏是一款耳熟能详的小游戏,通过上下左右控制蛇的方向,寻找吃的果子,每吃一口果子,蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自…

关于springboot中前端传递多个数组以及其他参数及json在前后端转变方法技巧的记录

文末含一种json的动态解析方法,感兴趣的大佬记得看到最后评论交流 * 因公司GIS保密要求仅放部分代码在这儿 前端传输json的方法 json格式不再赘述 常规json传递 使用formData封装传递 好处就是当页面同时传递多个数组甚至是同时传递数组和参数到后台,可以自定义…

2023计算机组成原理复习【1-4】

第一章 计算机系统概述 1.计算机语言的分类:高级语言,低级语言(汇编语言与机器语言)。P8 高级语言是人类可读写的编程语言。低级语言包括汇编语言和机器语言两种。汇编语言是一种直接使用符号代替计算机指令的语言&a…

C++静态对象的移动问题

7.1返回普通的静态对象 MyString func(const char* p) {static MyString tmp(p);return tmp; } int main() {MyString s1("hello");s1func("helloworld");s1.Print();MyString s2;s2func("hello");s2.Print();return 0; } 结果: 进…

Elagamal和ECC

Elgamal加密方案 椭圆曲线加密体制 椭圆曲线应该是非奇异的,曲线的图不会自我相交或者没有顶点。 椭圆曲线的基本运运算 相异点相加PQ: 相同点相加PP: ## 椭圆曲线加解密 加解密原理: Alice选取一个椭圆曲线 E p ( a , b ) E_p(a,b) Ep​…