Java基础:设计模式之建造者模式

建造者模式是一种创建型设计模式,其主要目的是将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。这种模式适用于创建那些包含多个组成部分、各部分之间有复杂的装配关系、且构造过程可能需要逐步进行或允许用户选择不同组件配置的产品对象。

结构与参与者

在建造者模式中,主要有以下几个关键角色:

  1. Product(产品类):定义了要构建的复杂对象的接口,通常包含多个组成部件。它不涉及具体的构建过程,仅定义产品的共有属性和行为。

  2. ConcreteProduct(具体产品类):实现了Product接口,是实际被构建的对象。

  3. Builder(抽象建造者):定义了一个包含一系列用于构建Product对象各个部件的抽象方法,通常还提供一个返回最终产品的接口(如getResult())。

  4. ConcreteBuilder(具体建造者):实现了Builder接口,负责实现构建过程的具体逻辑,即按照特定步骤创建并组装Product的各个部件。每个具体建造者都对应一种产品配置。

  5. Director(导演者/指挥者):负责协调建造过程,不直接参与对象的构建,而是通过调用Builder接口的方法来指导如何构建产品。它与具体的建造者解耦,使得客户端无需知道产品是如何被一步步构建出来的。

工作流程

  1. 客户端创建一个具体建造者(ConcreteBuilder)对象。
  2. 客户端通过Director以指定的步骤调用建造者的构建方法(如buildPartA(), buildPartB()等),逐步构建产品。
  3. 完成所有必要的构建步骤后,客户端可以通过建造者的getResult()方法获取最终构建好的Product对象。

示例说明

以创建一台电脑为例,我们可以定义如下类结构:

// Product: 电脑
public class Computer {
    private String cpu;
    private String memory;
    private String hardDisk;

    // 构造函数私有化,防止外界直接创建
    private Computer(String cpu, String memory, String hardDisk) {
        this.cpu = cpu;
        this.memory = memory;
        this.hardDisk = hardDisk;
    }

    // 提供获取电脑配置的getter方法
    // ...

    // 其他电脑相关的功能方法...
}

// Builder: 抽象电脑建造者
public abstract class ComputerBuilder {
    protected Computer computer; // 用于保存中间构建结果

    public void createNewComputer() {
        computer = new Computer("", "", "");
    }

    public abstract void buildCPU(String cpu);
    public abstract void buildMemory(String memory);
    public abstract void buildHardDisk(String hardDisk);

    public Computer getComputer() {
        return computer;
    }
}

// ConcreteBuilder: 高配电脑建造者
public class HighEndComputerBuilder extends ComputerBuilder {
    @Override
    public void buildCPU(String cpu) {
        computer.setCPU(cpu);
    }

    @Override
    public void buildMemory(String memory) {
        computer.setMemory(memory);
    }

    @Override
    public void buildHardDisk(String hardDisk) {
        computer.setHardDisk(hardDisk);
    }
}

// Director: 电脑装配厂
public class ComputerFactory {
    public Computer constructComputer(ComputerBuilder builder) {
        builder.createNewComputer();
        builder.buildCPU("Intel i9");
        builder.buildMemory("32GB DDR5");
        builder.buildHardDisk("1TB SSD");
        return builder.getComputer();
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        ComputerFactory factory = new ComputerFactory();
        ComputerBuilder builder = new HighEndComputerBuilder();

        Computer highEndComputer = factory.constructComputer(builder);
        System.out.println("Constructed high-end computer:");
        // 输出电脑配置...
    }
}

在这个例子中,Computer是产品类,ComputerBuilder是抽象建造者,HighEndComputerBuilder是具体建造者,ComputerFactory作为导演者角色,负责按照固定步骤调用建造者的构建方法来创建高配电脑。

适用场景

  1. 对象构造过程复杂:当一个对象的创建涉及多个步骤,这些步骤的顺序至关重要,或者某些步骤可能被省略,建造者模式能够清晰地封装这些复杂的构造逻辑。例如,创建一个包含多种零部件、配置选项多样的汽车、计算机或其他机械设备。

  2. 产品具有多种形态或配置:如果同一类型的产品可以根据客户需求或应用场景有不同的配置(如基础版、专业版、豪华版),每种配置对应一个具体建造者,这样可以方便地通过切换建造者来生成不同配置的产品,而无需在产品类中引入大量条件判断。

  3. 隔离复杂性:当产品类与创建过程过于复杂,以至于客户端代码难以理解或直接与之交互时,建造者模式可以将构建细节封装在建造者类中,使客户端只需与建造者接口交互,简化了客户端代码,同时隐藏了产品内部结构。

  4. 需要生成“零件列表”:在某些情况下,除了生成最终的产品对象外,还需要记录产品构建过程中使用的零件清单(如物料清单、成本计算等)。建造者模式可以在构建过程中收集这些信息,便于后续的报告生成或成本分析。

  5. 构建过程独立于产品组成部分:当构建过程独立于产品的具体组成部分(即构建算法与数据结构分离),且构建过程可能需要复用时,建造者模式能很好地分离这两部分,使得构建算法可以独立演化,提高代码的可维护性和扩展性。

  6. 需要支持递归构造:对于那些本身包含复杂树形结构或嵌套结构的产品(如XML文档、DOM树、菜单系统等),建造者模式可以自然地支持递归构造,通过递归调用建造者方法来构建嵌套结构。

  7. 需要延迟初始化:有时,出于性能、资源管理或依赖关系考虑,可能需要延迟初始化某些产品部件。建造者模式可以控制构建过程,确保在合适的时间点完成初始化。

存在的问题

尽管建造者模式能够有效地封装复杂对象的创建过程,但其使用也存在一些潜在问题:

  1. 代码膨胀:随着产品复杂性的增加,建造者类及其方法集可能会变得庞大,特别是当产品包含大量可选部件或配置时,可能会导致大量的建造者子类和构建方法。

  2. 过度设计:对于简单对象或者创建过程相对固定的场景,使用建造者模式可能会显得过于复杂,增加了不必要的抽象层次和类的数量。在这种情况下,简单的构造函数或者工厂方法可能就足够了。

  3. 灵活性与约束的平衡:为了保持构建过程的清晰和可控,建造者模式通常会限制客户端直接访问产品类的构造函数,这在一定程度上牺牲了灵活性。如果需要频繁改变产品的内部结构或添加新部件,可能需要修改建造者及其相关类。

  4. 适应变化的难度:当产品结构发生重大变化时,可能需要对所有的具体建造者进行相应的更新,这在大型项目中可能会带来一定的维护成本。

  5. 不适用动态产品结构:如果产品的组成部分或其组合方式在运行时才能确定,建造者模式可能不如其他动态生成对象的技术(如反射或脚本语言)灵活。

综上所述,建造者模式在处理复杂对象的创建、需要分步构建或支持多种不同配置的产品时非常有用,但应根据实际需求权衡其优点与可能带来的问题,避免在不需要复杂构建逻辑的情况下过度设计。

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

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

相关文章

股票分红扣税!详解现金分红、送红股和转增股本

股票分红 股票分红指的是上市公司根据其盈利情况,按照股东持有的股份比例,向股东分配利润的方式。股票分红需要满足一定的前提条件 1、公司必须存在可供分配的利润,公司在过去的经营活动中已经实现了盈利,并且这些盈利在缴纳了企…

【python技术】使用akshare抓取东方财富所有概念板块,并把指定板块概念的成分股保存excel 简单示例

最近有个想法,分析A股某个概念成分股情况进行分析,第一反应是把对应概念板块的成分股爬取下来。说干就干 下面是简单示例 import akshare as ak import pandas as pddef fetch_and_save_concept_stocks(name):# 获取指定股票概念的成分股,并…

宝塔面板mysql允许root账号登录

直接通过宝塔面板创建的mysql数据库,root是只允许localhost访问的,下面需要配置允许所有IP人员,都能访问 1、进入mysql: mysql -uroot -p 2、 使用mysql库: use mysql; 3. 查看用户表: SELECT Host,U…

K-近邻算法的 sklearn 实现

实验目的与要求 掌握基于 K-近邻分类算法的编程方法通过编程理解 K-近邻分类算法和该算法的基本步骤 实验器材 硬件:PC 机(参与实验的学生每人一台)软件环境:Python3.7 Pycharm 实验内容 使用 sklearn 库中的 neighbors 模块实…

C++深度解析教程笔记3

C深度解析教程笔记3 第5课 - 引用的本质分析实验-const引用实验-引用的本质实验-引用所占空间大小vs2010反汇编 实验-局部变量的引用小结 第6课 - 内联函数分析实验-内联函数设置允许编译器内联 实验-forceinline小结 本文学习自狄泰软件学院 唐佐林老师的 C深度解析教程&#…

做私域不止是积累流量,生态也很重要!

如今,私域流水占比已经逼近整个零售市场的30%,达到4万亿规模,百度、阿里、腾讯等头部玩家也都在加速布局,私域运营,已不再是一个单一的商业模式或者运营手段,而是逐渐构成一种可持续的行业生态。 一、什么…

el-form 表单设置某个参数非必填验证

html <el-form ref"form" :rules"rules"><el-form-item prop"tiktokEmail" label"邮箱" ><el-input v-model"form.tiktokEmail" placeholder"邮箱" ></el-input></el-form-item&…

Docker-容器的前世今生

文章目录 Docker为什么产生&#xff1f;硬件虚拟化硬件虚拟化解决的问题硬件虚拟化定义硬件虚拟化技术虚拟机的优点虚拟机的缺点 操作系统虚拟化即容器容器化解决的问题容器化定义容器化技术历史 容器和虚拟机对比 Docker的发展历史Docker架构客户端服务端仓库Registry Docker重…

民航电子数据库:mysql与cae(insert语法差异)

目录 示例1、cae插入数据时不支持value关键字&#xff0c;只能使用values2、insert时&#xff0c;就算是自增主键&#xff0c;只要新增时包含了主键&#xff0c;该主键就必须有值&#xff0c;否则会报错&#xff1a;字段xxx不能取空值 对接民航电子数据库&#xff0c;本篇记录i…

循环购模式:引领消费新潮流,共创商业新生态

大家好&#xff0c;我是吴军&#xff0c;今天我想和大家分享一个独特而富有吸引力的商业模式——循环购模式。这是一种融合了消费返利与积分机制的新型购物体验&#xff0c;它为消费者和商家带来了前所未有的互动机会。 在循环购模式的运作下&#xff0c;消费者的每次购物都伴随…

OSPF大作业

一&#xff0c;拓扑 二&#xff0c;要求 1&#xff0c;r4为ISP上只配ip&#xff0c;r3与其他设备之间只使用公有IP 2&#xff0c;r3-r5/6/7为MGRE环境&#xff0c;r3为中心 3&#xff0c;整个OSPF的ip地址基于172.16.0.0/16划分 所以设备都可以访问r4的环回 4减少LSA的数量加快…

【转载】C++代码中将函数返回类型后置有啥好处吗

C代码中将函数返回类型后置有啥好处吗&#xff1f; 内容如下&#xff1a; C代码中将函数返回类型后置有啥好处吗&#xff1f; 这种语法是 C11 新增的&#xff0c;学名叫 trailing return type[1]。翻译过来是后置返回类型&#xff0c;trailing 是后面的、拖尾的意思。书写 int …

质量管理,怎能不知道SPC?

SPC&#xff08;统计过程控制&#xff09;是质量管理的一个重要组成部分&#xff0c;它可以帮助企业更好地控制生产过程、提高产品质量、降低生产成本、增强企业的竞争力。 SPC是一种应用统计技术对过程中的各个阶段进行评估和监控&#xff0c;建立并保持过程处于可接受的并且稳…

深入理解Linux调试工具eBPF和strace、内存泄漏处理、Kubernetes容器调试以及C++协程的崩溃信息收集

在软件开发领域&#xff0c;无论是初级开发者还是资深工程师&#xff0c;都需要面对复杂的调试工作。本文将介绍几个重要的调试工具和技术&#xff0c;并提供实际调试方法的指导&#xff0c;包括Linux环境下的eBPF和strace&#xff0c;内存泄漏问题的处理&#xff0c;Kubernete…

020Node.js的FS模块使用fs.mkdir创建目录

Node.js的FS模块使用fs.mkdir创建目录 //fs.mkdir 创建目录 /*path 将创建的目录路径mode 目录权限&#xff08;读写权限&#xff09;&#xff0c;默认777callback 回调&#xff0c;传递异常参数err*/ const fsrequire(fs);fs.mkdir(./css,(err)>{if(err){console.log(err)…

时间序列模型(含python程序实现)

常用按时间顺序排列的一组随机变量来表示一个随机事件的时间序列&#xff0c;简记为 用表示该随机序列的n个有序观察值&#xff0c;称之为序列长度为n的观察值序列。 常用的时间序列模型 时间序列的预处理 拿到一个观察值序列后&#xff0c;首先要对它的纯随机性和平稳性进行…

PC-3000 Mobile Pro: 智能手机及平板设备数据提取及取证工具

天津鸿萌科贸发展有限公司从事数据安全业务20余年&#xff0c;在数据恢复、数据取证、数据备份等领域有丰富的案例经验、前沿专业技术及良好的行业口碑。同时&#xff0c;公司面向取证机构及数据恢复公司&#xff0c;提供数据恢复实验室建设方案&#xff0c;包含数据恢复硬件设…

书生·浦语 大模型(学习笔记-9)大模型微调的相关概念 预训练 与 微调 全量微调FFT 与 PEFT的区别

目录 一、什么是大模型微调 二、指令微调 三、微调的目的 三、微调的方式 四、微调的步骤 五、微调数据准备 六、微调的数据质量 一、什么是大模型微调 预训练和微调的区别&#xff0c;这个很关键 二、指令微调 这个地方主要是微调的角度不同&#xff0c;简单理解&#…

linux jmeter ant下载并安装【2024-亲测】

环境 centos7 一、下载jmeter 在这里插入代码片wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz --no-check-certificate解压 tar -zxvf apache-jmeter-5.6.3.tgz复制到安装目录、设置环境变量 vim /etc/profile添加环境变量&#xff0c;路径改成…

YOLOv8: 快速而准确的对象检测

YOLOv8: 快速而准确的对象检测 背景 对象检测是计算机视觉中的一个关键任务,它可以帮助我们在图像或视频中识别和定位感兴趣的物体。其中,YOLO(You Only Look Once)系列是一类非常出色的实时对象检测算法,以其快速和准确的特点而闻名。YOLOv8是YOLO系列的最新版本,由Ultralyti…
最新文章