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

建造者模式

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

建造者模式

概述

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

  • 分离了部件的构建(由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;}@Overridepublic 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{@Overridepublic Computer createComputer() {return computer;}@Overridepublic void builderMemory() {computer.setMemory("8G");}@Overridepublic void builderHardDrive() {computer.setMemory("512G");}@Overridepublic void builderMotherBoard() {computer.setMotherBoard("一块好板");}@Overridepublic void builderPowerSource() {computer.setPowerSource("600w");}@Overridepublic void builderCpu() {computer.setCpu("i5");}
}
/*** 惠普电脑构建者 实现抽象构建者类*/
public class PHComputerBuilder extends Builder{@Overridepublic Computer createComputer() {return computer;}@Overridepublic void builderMemory() {computer.setMemory("16G");}@Overridepublic void builderHardDrive() {computer.setHardDrive("512G");}@Overridepublic void builderMotherBoard() {computer.setMotherBoard("普通的主板");}@Overridepublic void builderPowerSource() {computer.setPowerSource("500w");}@Overridepublic 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);}}@Overridepublic 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.mzph.cn/news/212769.shtml

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

相关文章

办公word-从不是第一页添加页码

总结 实际需要注意的是,分隔符、分节符和分页符并不是一个含义 分隔符包含其他两个;分页符:是增加一页;分节符:指将文档分为几部分。 从不是第一页插入页码1步骤 1,插入默认页码 自己可以测试时通过**…

win11 powershell conda 激活环境后不显示环境名称

win11 powershell conda 激活环境后不显示环境名称 问题现象解决方法 问题现象 安装 Anaconda 后在 powershell 中激活环境后,命令行前面不显示环境名称 解决方法 在 powershell 中执行 conda init 重新打开 poweshell 出现以下问题,请参考 win11 p…

HarmonyOS鸿蒙应用开发——HTTP网络访问与封装

文章目录 基本使用封装参考 基本使用 鸿蒙应用发起HTTP请求的基本使用,如下: 导入http模块创建httpRequest对象发起http请求,并处理响应结果 第一、导入http模块: import http from ohos.net.http第二、创建httpRequest对象&a…

二分查找|滑动窗口|前缀和|LeetCode209: 长度最小的子数组

长度最短的子数组 作者推荐 【动态规划】【广度优先】LeetCode2258:逃离火灾 本文涉及的基础知识点 二分查找算法合集 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 滑动窗口 题目 给定一个含有 n 个正整数的数组和一个正整数 target…

在IDEA中创建Maven项目时没有src文件、不自动配置文件

错误示例: 没有src文件,并且没有自动下载相关的配置文件 对我这中情况无效的解决办法: ①配置好下列图中圈出来的文件 ②在VM选项中输入:“-DarchetypeInternal” ③点击应用,再点击确定 ④还是不行 解决办法&#x…

GridBagLayout GridBagConstraints 笔记231130

实例化使用模板 GridBagLayout gbl new GridBagLayout(); // gbl.columnWidths new int[]{200,200,200}; // 用数组设置列 // gbl.rowHeights new int[]{100,100,100,100,100}; // 用数组设置行GridBagConstraints gbc new GridBagConstraints();/*** gridBagConstrain…

14-1、IO流

14-1、IO流 lO流打开和关闭lO流打开模式lO流对象的状态 非格式化IO二进制IO读取二进制数据获取读长度写入二进制数据 读写指针 和 随机访问设置读/写指针位置获取读/写指针位置 字符串流 lO流打开和关闭 通过构造函数打开I/O流 其中filename表示文件路径,mode表示打…

【KCC@南京】KCC南京“数字经济-开源行”活动回顾录

11月26日,由KCC南京、中科南京软件研究所、傲空间、PowerData联合主办的 KCC南京“数字经济-开源行” 的活动已圆满结束。此次活动,3 场主题研讨,11 场分享,现场参会人数 60,线上直播观看 3000,各地小伙伴从…

Android画布Canvas绘图scale,Kotlin

Android画布Canvas绘图scale&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.…

数据仓库工具Hive

1. 请解释Hive是什么&#xff0c;它的主要用途是什么&#xff1f; Hive是一个基于Hadoop的数据仓库工具&#xff0c;主要用于处理和分析大规模结构化数据。它可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类似SQL的查询功能&#xff0c;将SQL语句转换为MapRedu…

Windows 和 MacOS 上安装配置ADB(安卓调试桥)

一、Android 调试桥 (ADB) Android 调试桥&#xff08;ADB&#xff09; 是一款多功能命令行工具&#xff0c;它让你能够更便捷地访问和管理 Android 设备。使用 ADB 命令&#xff0c;你可以轻松执行以下操作 在设备上安装、复制和删除文件&#xff1b;安装应用程序&#xff1…

YOLOV3 SPP 目标检测项目(针对xml或者yolo标注的自定义数据集)

1. 目标检测的两种标注形式 项目下载地址:YOLOV3 SPP网络对自定义数据集的目标检测(标注方式包括xml或者yolo格式) 目标检测边界框的表现形式有两种: YOLO(txt) : 第一个为类别,后面四个为边界框,x,y中心点坐标以及h,w的相对值 xml文件:类似于网页的标注文件,里面会…

JavaEE 08 线程池简介

前言 前面我们谈完了定时器,单例模式,阻塞队列等的操作并且做了模拟实现,今天我们再来说一说线程池的操作以及一些锁策略. 注:本章几乎均为理论篇,实践较少. 下面就让我们开始吧. 线程池 我们知道因为进程的频繁创建和销毁,带来的开销过大,我们无法接受,所以我们引入了更轻量级…

Linux常见压缩指令小结

为什么需要压缩技术 我们都知道文件是以byte作为单位的&#xff0c;如果我们的文件仅仅在低位占一个1 0000 0001这种情况我们完全可以压缩一下&#xff0c;将高位的0全部抹掉即可。 如上所说是一种压缩技术&#xff0c;还有一种就是将1111(此处省略96个)一共100个1&#xff0…

mysql执行带函数命令的sql脚本报错

一、前言 开发给了一个带函数的sql文件让我执行&#xff0c;但是执行导入时报以下错误 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled 二、解决 在数据库命令行中执行以下命令&#xff08;临时生效&…

HarmonyOS4.0从零开始的开发教程11给您的应用添加弹窗

HarmonyOS&#xff08;十&#xff09;给您的应用添加弹窗 概述 在我们日常使用应用的时候&#xff0c;可能会进行一些敏感的操作&#xff0c;比如删除联系人&#xff0c;这时候我们给应用添加弹窗来提示用户是否需要执行该操作&#xff0c;如下图所示&#xff1a; 弹窗是一种…

AI:99-基于深度学习的飞机故障检测与维修

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的核心代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新…

【pycharm】Pycharm中进行Git版本控制

本篇文章主要记录一下自己在pycharm上使用git的操作&#xff0c;一个新项目如何使用git进行版本控制。 文章使用的pycharm版本PyCharm Community Edition 2017.2.4&#xff0c;远程仓库为https://gitee.com/ 1.配置Git&#xff08;File>Settings&#xff09; 2.去Gitee创建…

记录一次云原生线上服务数据迁移全过程

文章目录 背景迁移方案调研迁移过程服务监控脚本定时任务暂停本地副本服务启动&#xff0c;在线服务下线MySQL 数据迁移Mongo 数据迁移切换新数据库 ip 本地服务启动数据库连接验证服务打包部署服务重启前端恢复正常监控脚本定时任务启动旧服务器器容器关闭 迁移总结 背景 校园…

机器学习基本概念介绍 2023

笔记来源于&#xff1a; https://www.youtube.com/watch?vphQK8xZpgoU&t172s https://www.youtube.com/watch?vXLyPFnephpY&t645s Machine/Deep Learning 机器学习概况来说&#xff0c;让机器具备自动找函式的能力 &#xff08;Machine Learning 约等于 Looking …