【设计模式--创建型--建造者模式】

建造者模式

    • 建造者模式
      • 概述
      • 结构
      • 结果
      • 优缺点
      • 使用场景
    • 将上述案例改为链式调用
      • 结果

建造者模式

概述

将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

  • 分离了部件的构建(由Builder来负责)和装配(由Director负责)。从而可以构建出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。
  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。实现了更好的复用。
  • 建造者模式可以将部件与其组装过程分开,一步一步创建一个复杂对象。用户只需要指定复杂对象的类型就可以获得该对象,而无需知道内部的构造细节。

结构

建造者(Builder)模式包含如下角色:

  • 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
  • 具体建造者类(ConcreteBuilder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
  • 产品类(Product):要创建的复杂对象
  • 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各个部分完整创建或按某种顺序创建。
    类图:
    在这里插入图片描述
/**
 * 抽象建造者类
 */
public abstract class Builder {
    // 声明computer类型的变量,并赋值
    protected Computer computer = new Computer();
    public abstract Computer createComputer();
    public abstract void builderMemory();
    public abstract void builderHardDrive();
    public abstract void builderMotherBoard();
    public abstract void builderPowerSource();
    public abstract void builderCpu();
}
/**
 * 电脑类
 */
public class Computer {

    private String memory;
    private String hardDrive;
    private String motherBoard;
    private String powerSource;
    private String cpu;

    public String getMemory() {
        return memory;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public String getHardDrive() {
        return hardDrive;
    }

    public void setHardDrive(String hardDrive) {
        this.hardDrive = hardDrive;
    }

    public String getMotherBoard() {
        return motherBoard;
    }

    public void setMotherBoard(String motherBoard) {
        this.motherBoard = motherBoard;
    }

    public String getPowerSource() {
        return powerSource;
    }

    public void setPowerSource(String powerSource) {
        this.powerSource = powerSource;
    }

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "memory='" + memory + '\'' +
                ", hardDrive='" + hardDrive + '\'' +
                ", motherBoard='" + motherBoard + '\'' +
                ", powerSource='" + powerSource + '\'' +
                ", cpu='" + cpu + '\'' +
                '}';
    }
}
/**
 * 指挥者类
 */
public class Director {
    // 声明builder类型的变量
    private Builder builder;
    public Director(Builder builder){
        this.builder =builder;
    }
    // 组装电脑
    public Computer construct(){
        builder.builderMotherBoard();
        builder.builderCpu();
        builder.builderMemory();
        builder.builderHardDrive();
        builder.builderPowerSource();
        return builder.createComputer();
    }
}
/**
 * 联想电脑构建者 实现抽象构建者类
 */
public class LXComputerBuilder extends Builder{
    @Override
    public Computer createComputer() {
        return computer;
    }

    @Override
    public void builderMemory() {
        computer.setMemory("8G");
    }

    @Override
    public void builderHardDrive() {
        computer.setMemory("512G");
    }

    @Override
    public void builderMotherBoard() {
        computer.setMotherBoard("一块好板");
    }

    @Override
    public void builderPowerSource() {
        computer.setPowerSource("600w");
    }

    @Override
    public void builderCpu() {
        computer.setCpu("i5");
    }
}
/**
 * 惠普电脑构建者 实现抽象构建者类
 */
public class PHComputerBuilder extends Builder{

    @Override
    public Computer createComputer() {
        return computer;
    }

    @Override
    public void builderMemory() {
        computer.setMemory("16G");
    }

    @Override
    public void builderHardDrive() {
        computer.setHardDrive("512G");
    }

    @Override
    public void builderMotherBoard() {
        computer.setMotherBoard("普通的主板");
    }

    @Override
    public void builderPowerSource() {
        computer.setPowerSource("500w");
    }

    @Override
    public void builderCpu() {
        computer.setCpu("i7");
    }
}
public class Test01 {
    public static void main(String[] args) {
        // 创建指挥者类,传入惠普电脑构建者类
        Director director = new Director(new PHComputerBuilder());
        // 调用指挥者类的构建方法,构建惠普电脑
        Computer construct = director.construct();
        System.out.println(construct.toString());
    }
}

结果

在这里插入图片描述

优缺点

  • 优点:
    • 建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在指挥者类中对整体而而言可以取得比较好的稳定性。
    • 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
    • 可以更加精细的控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也方便使用程序来控制创建过程。
    • 建造者模式很容易进行扩展。如果由新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前的代码,符合开闭原则。
  • 缺点:
    • 建造者模式所创建的产品一般具有较多共同点,其组成部分相似,如果产品之间差异很大,则不适用建造者模式,因此使用范围受到一定的限制。

使用场景

建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临剧烈的变化,但是将他们组合在一起的算法却相对稳定,所有通常在一下场合使用:

  • 创建的对象较复杂,由多个部件构成,各部件面临复杂变化,但构建顺序是相对稳定的
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的

将上述案例改为链式调用

在这里插入图片描述

/**
 * 电脑类
 */
public class Computer {

    private String memory;
    private String hardDrive;
    private String motherBoard;
    private String powerSource;
    private String cpu;

    // 构造方法
    public Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.hardDrive = builder.hardDrive;
        this.motherBoard = builder.motherBoard;
        this.powerSource = builder.powerSource;
        this.memory = builder.memory;
    }
    // 将创建者声明为静态内部类
    public static final class Builder {
        private String memory;
        private String hardDrive;
        private String motherBoard;
        private String powerSource;
        private String cpu;
        
        public Builder cpu(String cpu){
            this.cpu = cpu;
            return this; // 直接返回 this,即 Builder对象
        }
        public Builder powerSource(String powerSource){
            this.powerSource = powerSource;
            return this;
        }
        public Builder motherBoard(String motherBoard){
            this.motherBoard = motherBoard;
            return this;
        }
        public Builder hardDrive(String hardDrive){
            this.hardDrive = hardDrive;
            return this;
        }
        public Builder memory(String memory){
            this.memory = memory;
            return this;
        }
        // 直接调用Computer类的构造方法,传入this,即 Builder对象
        public Computer build(){
            return new Computer(this);
        }
    }
    
    @Override
    public String toString() {
        return "Computer{" +
                "memory='" + memory + '\'' +
                ", hardDrive='" + hardDrive + '\'' +
                ", motherBoard='" + motherBoard + '\'' +
                ", powerSource='" + powerSource + '\'' +
                ", cpu='" + cpu + '\'' +
                '}';
    }
}
public class Test02 {
    public static void main(String[] args) {
        Computer computer = new Computer.Builder()
                .cpu("i9")
                .hardDrive("2T")
                .memory("32G")
                .powerSource("1000w")
                .motherBoard("华硕")
                .build();

        System.out.println(computer);
    }
}

结果

在这里插入图片描述

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

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

相关文章

接触刚性环境任务下的机器人力控(阻抗)性能测试

内涵 接触刚性环境任务下的机器人力控(阻抗)性能测试旨在评估机器人在与刚性物体交互时的性能表现。这种测试通过调整机器人的控制参数,如期望刚度和期望阻尼等,并分析记录的数据,旨在确保机器人能够在执行任务时保持…

类数组对象转为数组的方法

在开发的过程经常会遇到一些类数组对象,例如arguments,类数组对象具有length属性,也可以通过下标访问到对应值,但是不能使用数组的方法,如果将类数组对象转为数组,数组方法可以帮助我们更快实现逻辑&#x…

C++枚举类

枚举 C11有作用域枚举和无作用域枚举 无作用域枚举 特点 全局作用域:无作用域枚举的成员(枚举值)在包含它们的作用域内是直接可见的,不需要使用枚举类型名称作为前缀。 隐式类型转换:无作用域枚举的成员可以隐式地转换…

机器学习 | Python贝叶斯超参数优化模型答疑

机器学习 | Python贝叶斯超参数优化模型答疑 目录 机器学习 | Python贝叶斯超参数优化模型答疑问题汇总问题1答疑问题2答疑问题3答疑问题汇总 问题1:想问一下贝叶斯优化是什么? 问题2:为什么使用贝叶斯优化? 问题3:如何实现? 问题1答疑 超参数优化在大多数机器学习流水线…

ToolkenGPT:用大量工具增强LLM

深度学习自然语言处理 原创作者:cola 用外部工具增强大型语言模型(LLM)已经成为解决复杂问题的一种方法。然而,用样例数据对LLM进行微调的传统方法,可能既昂贵又局限于一组预定义的工具。最近的上下文学习范式缓解了这一问题,但有…

微信小程序pc端宽高:默认宽高为1024*812,全屏宽高为1920*1032

最近开发调试pc端小程序,想知道默认打开和全屏这两种情况下的小程序宽高,发现了一种方法: 真机运行pc端小程序,点击devTools 在控制台直接打印window对象,可以获取到pc端默认屏幕宽高为1024*812,全屏pc端小…

Go开发运维:Go服务发布到K8S集群

目录 一、实验 1.Go服务发布到k8s集群 二、问题 1.如何从Harbor拉取镜像 一、实验 1.Go服务发布到k8s集群 (1)linux机器安装go(基于CentOS 7系统) yum install go -y (2)查看版本 go version (3)创…

有病但合理的 ChatGPT 提示语

ChatGPT 面世一年多了,如何让大模型输出高质量内容,让提示词工程成了一门重要的学科。以下是一些有病但合理的提示词技巧,大部分经过论文证明,有效提高 ChatGPT 输出质量: ​1️⃣ Take a deep breath. 深呼吸 ✨ 作用…

【Kubernetes】持久化存储emptyDir/hostPath/nfs/PVC

k8s持久化存储 一、为什么做持久化存储?二、k8s持久化存储:emptyDir三、k8s持久化存储:hostPath四、k8s持久化存储:nfs4.1、搭建nfs服务4.2、挂载nfs共享目录 五、k8s持久化存储: PVC5.1、什么是PV5.2、什么是PVC5.3、…

ansible中的角色

1.理解roles在企业中的定位及写法 查看创建目录结构 ansible - galaxy list 指定新的位置 vim ansible.cfg roles_path ~/.ansible/roles 建立项目 cd roles/ ansible-galaxy init vsftpd tree vsftpd/ 编辑任务执行(顺序)文件 vim vsftpd/tas…

Day56力扣打卡

打卡记录 数对统计&#xff08;DP状态压缩&#xff09; 参考文献 #include <bits/stdc.h>using namespace std;void solve(){int n;cin >> n;map<int, int> mapp;vector<int> a(n);for (auto& x : a){cin >> x;mapp[x] ;}vector<array&…

C语言动态内存经典笔试题分析

C语言动态内存经典笔试题分析 文章目录 C语言动态内存经典笔试题分析1. 题目一2. 题目二3. 题目三4. 题目四 1. 题目一 void GetMemory(char *p){p (char *)malloc(100);} void Test(void){char *str NULL;GetMemory(str);strcpy(str, "hello world");printf(str)…

Mybatis与Spring结合深探——MapperFactoryBean的奥秘

文章目录 前言MapperFactoryBean的工作原理底层实现剖析MapperFactoryBean的checkDaoConfig()方法总结 MapperFactoryBean的getObject()方法 思考联想后续 系列相关相关文章究竟FactoryBean是什么&#xff1f;深入理解Spring的工厂神器超硬核解析Mybatis动态代理原理&#xff0…

transformer模型结构|李宏毅机器学习21年

来源&#xff1a;https://www.bilibili.com/video/BV1Bb4y1L7FT?p4&vd_sourcef66cebc7ed6819c67fca9b4fa3785d39 文章目录 概述seq2seqtransformerEncoderDecoderAutoregressive&#xff08;AT&#xff09;self-attention与masked-self attentionmodel如何决定输出的长度…

DL Homework 10

习题6-1P 推导RNN反向传播算法BPTT. 习题6-2 推导公式(6.40)和公式(6.41)中的梯度 习题6-3 当使用公式(6.50)作为循环神经网络的状态更新公式时&#xff0c; 分析其可能存在梯度爆炸的原因并给出解决方法&#xff0e; 当然&#xff0c;因为我数学比较菜&#xff0c;我看了好半…

你知道红细胞基因对单细胞分析的影响吗

大家好&#xff0c;今天周日。最近发现有些单细胞测序数据结果不是很好&#xff0c;或许在作者取样的时候&#xff0c;就注定了后续的生信分析不会太成功~ 本次主要发现一个数据集中出现一大群红细胞基因高表达亚群&#xff0c;对后续分析影响还是挺大的。下面先介绍一下为啥单…

dell r720远程网络安装ubuntu20.04(无U盘)

登陆后界面&#xff0c;在主界面上&#xff0c;我们就可以看到各个硬件组件的状态。在快速启动任务栏中&#xff0c;可以对系统电源进行操作&#xff0c;如开机、关机等。安装操作系统&#xff0c;在虚拟控制台预览处点击>启动 按照浏览器出现的提示确定安装控件等&#x…

4-SpringMVC

文章目录 项目源码地址回顾-MVC什么是MVC&#xff1f;MVC各部分组成 回顾-ServletMaven创建Web项目1、创建Maven父工程pom&#xff0c;并导入依赖2、用Maven新建一个Web Module3、代码&#xff1a;HelloServlet.java3、代码-hello.jsp3、代码-web.xml4、配置Tomcat5、浏览器测试…

“快速排序:一种美丽的算法混沌”(1.hoare)

欢迎来到我的博客&#xff01;在今天的文章中&#xff0c;我将采用一种独特且直观的方式来探讨我们的主题&#xff1a;我会使用一幅图像来贯穿整篇文章的讲解。这幅精心设计的图表不仅是我们讨论的核心&#xff0c;也是一个视觉辅助工具&#xff0c;帮助你更深入地理解和掌握本…
最新文章