9.建造者模式

news2025/2/24 11:36:03

文章目录

  • 一、介绍
  • 二、代码
  • 三、实际使用
  • 总结


一、介绍

建造者模式旨在将一个复杂对象的构建过程和其表示分离,以便同样的构建过程可以创建不同的表示。这种模式适用于构建对象的算法(构建过程)应该独立于对象的组成部分以及它们的装配方式的情景。

建造者模式通常包含以下角色:

  1. 产品(Product): 表示被构建的复杂对象。在建造者模式中,产品是由多个部件组成的。

  2. 抽象建造者(Builder): 声明了创建产品各个部件的抽象接口。通常包括创建和装配部件的方法。

  3. 具体建造者(Concrete Builder): 实现抽象建造者接口,负责具体部件的创建和装配。每个具体建造者都定义了自己的方式来构建产品。

  4. 指导者(Director): 负责使用建造者接口来构建产品对象。通常包含一个构建方法,该方法定义了构建产品的顺序。

二、代码

结构图

在这里插入图片描述

代码

/**
 * 产品类,由多个部件构成
 */
public class Product {

    private List<String> parts = new ArrayList<>();

    public void add(String part) {
        parts.add(part);
    }

    public void show(){
        System.out.println("产品部件 --->");
        for (String part : parts) {
            System.out.print(part+" ");
        }
    }
}
/**
 * 抽象建造者类,确定产品由两个部件构成,并声明一个得到产品的方法
 */
abstract class Builder{
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult();
}
class Builder1 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.add("部件a");
    }

    @Override
    public void buildPartB() {
        product.add("部件b");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
class Builder2 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.add("部件x");
    }

    @Override
    public void buildPartB() {
        product.add("部件y");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
/**
 * 指挥者类,用来指挥构建过程
 */
class Director {
    public Product Construct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
        return builder.getResult();
    }
}
public static void main(String[] args) {
    Director director = new Director();
    Builder1 builder1 = new Builder1();
    Builder2 builder2 = new Builder2();
    
    Product result1 = director.Construct(builder1);
    result1.show();

    Product result2 = director.Construct(builder2);
    result2.show();
}

三、实际使用

场景

假设我们要创建一个汽车对象,汽车有多个可选的配置,包括引擎类型、车身颜色、轮胎类型等。我们将使用建造者模式来实现汽车对象的配置灵活性。

代码

// 产品类:汽车
class Car {
    private String engineType;
    private String bodyColor;
    private String tireType;

    // 构造方法私有化,只能通过建造者来构建对象
    private Car() {
    }

    public String getEngineType() {
        return engineType;
    }

    public String getBodyColor() {
        return bodyColor;
    }

    public String getTireType() {
        return tireType;
    }

    // 静态内部类作为具体建造者
    public static class Builder {
        private Car car;

        public Builder() {
            this.car = new Car();
        }

        public Builder setEngineType(String engineType) {
            car.engineType = engineType;
            return this;
        }

        public Builder setBodyColor(String bodyColor) {
            car.bodyColor = bodyColor;
            return this;
        }

        public Builder setTireType(String tireType) {
            car.tireType = tireType;
            return this;
        }

        // 构建汽车对象
        public Car build() {
            return car;
        }
    }
}

// 客户端
public class BuilderPatternFlexibilityExample {
    public static void main(String[] args) {
        // 使用建造者模式构建汽车对象,并灵活配置
        Car car1 = new Car.Builder()
                .setEngineType("V8")
                .setBodyColor("Red")
                .setTireType("Summer")
                .build();

        Car car2 = new Car.Builder()
                .setEngineType("Hybrid")
                .setBodyColor("Blue")
                .build();

        // 输出构建好的汽车对象
        System.out.println("Car 1 - Engine Type: " + car1.getEngineType() +
                ", Body Color: " + car1.getBodyColor() +
                ", Tire Type: " + car1.getTireType());

        System.out.println("Car 2 - Engine Type: " + car2.getEngineType() +
                ", Body Color: " + car2.getBodyColor() +
                ", Tire Type: " + car2.getTireType());
    }
}

上面的例子中,Car 是产品类,Car.Builder 是具体建造者。通过具体建造者,我们可以设置汽车的各个可选配置,最后通过 build 方法得到一个完整的汽车对象。客户端可以根据实际需求来选择设置不同的配置,实现了对象配置的灵活性。这种方式可以避免创建多个构造函数以应对各种配置组合的情况,使得代码更加简洁和可维护。

总结

上面的代码中,我们通过不同的具体建造者,同一个指挥者,获得了不一样的产品。在我们平时的情况中,以下的场景可以用到建造者模式

  1. 创建复杂对象: 当一个对象的构建过程比较复杂,涉及多个步骤、部件组合或配置选项时,建造者模式可以将构建过程与最终表示分离,使得代码更清晰、可维护。

  2. 对象的配置灵活性: 当需要创建的对象具有多个配置选项,而客户端希望能够以不同的方式组装对象时,建造者模式可以提供更灵活的配置选择,而无需创建大量的构造函数。

  3. 避免构造器参数过多: 当一个对象的构造函数参数过多,而且可能存在多个可选参数时,使用建造者模式可以避免创建过多的构造函数,使得代码更加清晰。

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

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

相关文章

性能分析与调优: Linux 文件系统观测工具

目录 一、实验 1.环境 2.mount 3.free 4.top 5.vmstat 6.sar 7.slabtop 8.strace 9.opensnoop 10.filetop 11.cachestat 二、问题 1.Ftrace实例如何实现 2.Function trace 如何跟踪实例 3.function_graph Trace 如何跟踪实例 4.trace event 如何跟踪实例 5.未…

Uibot (RPA设计软件)微信群发助手机器人————课前材料二

(本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; 紧接着小北的前两篇博客&#xff0c;友友们我们即将开展新课的学习~RPA 培训前期准备指南——安装Uibot(RPA设计软件&#xff09;-CSDN博客https://blog.csdn.net/Zhiyilang/article/details/1…

AI实景无人直播 矩阵系统

矩阵系统&#xff1a;重塑未来的组织与沟通在不断变化的世界中&#xff0c;我们需要的不仅是适应变化的能力&#xff0c;更需要预见未来的视角。矩阵系统&#xff0c;正是一个能够助力我们应对复杂环境、实现高效组织和沟通的工具。一、矩阵系统的核心价值矩阵系统&#xff0c;…

案例分享:当前高端低延迟视频类产品方案分享(内窥镜、记录仪、车载记录仪、车载环拼、车载后视镜等产品)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/135439369 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

RPA财务机器人在厦门市海沧医院财务管理流程优化汇总的应用

目前国内外研究人员对于RPA机器人在财务管理流程优化领域中的应用研究层出不穷&#xff0c;但现有研究成果主要集中在财务业务单一领域&#xff0c;缺乏财务管理整体流程一体化管控的研究。RPA机器人的功能绝非单一的财务业务处理&#xff0c;无论从自身技术发展&#xff0c;或…

Adding Conditional Control to Text-to-Image Diffusion Models——【论文笔记】

本文发表于ICCV2023 论文地址&#xff1a;ICCV 2023 Open Access Repository (thecvf.com) 官方实现代码&#xff1a;lllyasviel/ControlNet: Let us control diffusion models! (github.com) Abstract 论文提出了一种神经网络架构ControlNet,可以将空间条件控制添加到大型…

面试宝典进阶之Java线程面试题

T1、【初级】线程和进程有什么区别&#xff1f; &#xff08;1&#xff09;线程是CPU调度的最小单位&#xff0c;进程是计算分配资源的最小单位。 &#xff08;2&#xff09;一个进程至少要有一个线程。 &#xff08;3&#xff09;进程之间的内存是隔离的&#xff0c;而同一个…

2024阿里云服务器ECS实例全方位介绍_优缺点大全

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网aliyu…

EMQX5设置客户端连接认证

文章目录 说明配置客户端连接认证配置1、访问控制-客户端认证-创建2、选择“密码”方式-下一步3、选择“内置数据库”-下一步4、账号类型选择“username”5、密码加密方式选择“plain”6、加盐方式“disable”-创建7、添加客户端连接的账密客户端连接验证 心得 说明 号外&…

CST2024的License服务成功启动,仍报错——“The desired daemon is down...”,适用于任何版本!基础设置遗漏!

CST2024的License服务成功启动&#xff0c;仍报错——“The desired daemon is down…”&#xff0c;适用于任何版本&#xff01;基础设置遗漏&#xff01; CST2024的License服务成功启动后报错 若不能成功启动License服务&#xff0c;有可能是你的计算机名称带中文&#xff…

20240105移远的4G模块EC20在Ubuntu 20.04.6 LTS下使用联通5G卡上网的步骤

20240105移远的4G模块EC20在Ubuntu 20.04.6 LTS下使用联通5G卡上网的步骤 2024/1/5 10:11 缘起&#xff1a;需要在Firefly的AIO-3399J开发板上调试移远的4G模块EC20&#xff08;Android10/11/12&#xff09;&#xff0c;需要现在先测试EC20的好坏&#xff01; 陶老板告诉我找一…

ADS1110负电压采集

先说结论&#xff1a; 无法采集绝对的负电压&#xff08;供电电压范围之外&#xff09;。 ADS1110 16位AD转换问题 ads1110负电压采集 ADS1110是差分输入形式 在数据手册上有一个参数 模拟输入端VIN 的输入电压 最大是VDD0.2 最小是GND-0.2 模拟输入端VIN- 的输入也是这样…

C#PDF转Excel

組件 Spire.Pdf.dll, v7.8.9.0 【注意&#xff1a;版本太低的没有此功能】 在Visual Studio中找到参考&#xff0c;鼠标右键点击“引用”&#xff0c;“添加引用”&#xff0c;将本地路径debug文件夹下的dll文件添加引用至程序。 界面图&#xff1a; 1个label&#xff0c;1…

【服务器数据恢复】FreeNAS+ESXi数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器&#xff0c;虚拟化系统为esxi&#xff0c;上层使用iSCSI的方式实现FC SAN功能&#xff0c;iSCSI通过FreeNAS构建。 FreeNAS采用了UFS2文件系统&#xff0c;esxi虚拟化系统里有3台虚拟机&#xff1a;其中一台虚拟机安装FreeBSD系统&a…

JAVA面向对象基础-容器

一、泛型 我们可以在类的声明处增加泛型列表&#xff0c;如&#xff1a;<T,E,V>。 此处&#xff0c;字符可以是任何标识符&#xff0c;一般采用这3个字母。 【示例9-1】泛型类的声明 1 2 3 4 5 6 7 8 9 10 class MyCollection<E> {// E:表示泛型; Object[] o…

20240109适配selinux让移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通

20240109适配selinux让移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通 2024/1/9 10:46 缘起&#xff1a;使用友善之臂的Android11可以让EC20上网&#xff0c;但是同样的修改步骤&#xff0c;Toybrick的Android11不能让EC20上网。 最后确认是selinux的问题&#…

Linux--防火墙,实验案例:基于区域、服务、端口的访问控制

实验环境 某公司的Web服务器&#xff0c;网关服务器均采用Linux CentOS 7.3操作系统&#xff0c;如图2.13所示。为了 加强网络访问的安全性&#xff0c;要求管理员熟悉firewalld防火墙规则的编写&#xff0c;以便制定有效、可行的主机防护策略。 需求描述 > 网关服务器ens3…

【计算机网络】TCP原理 | 可靠性机制分析(二)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程、计算机网络的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; T…

Kettle Local引擎使用记录(一)(基于Kettle web版数据集成开源工具data-integration源码)

Kettle Web &#x1f4da;第一章 前言&#x1f4da;第二章 demo源码&#x1f4d7;pom.xml引入Kettle引擎核心文件&#x1f4d7;java源码&#x1f4d5; controller&#x1f4d5; service&#x1f4d5; 其它&#x1f4d5; maven settings.xml &#x1f4d7;测试&#x1f4d5; 测试…

C语言中关于函数递归的理解

递归的概念&#xff1a;如果一个对象部分包含它自己,或者利用自己定义自己,则称这个对象是递归的;如果 一个过程直接或间接调用自己,则称这个过程是一个递归过程。递归的主要思考方式在于&#xff1a;将大事化小 我们先看一个例子 题目&#xff1a;输入一个无符号数&#xff0…