Java设计模式中建造者模式是啥/建造者模式实现细节是什么/工厂模式,抽象工厂与建造者模式之间区别是啥

news2025/1/23 10:43:01

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

4.6 建造者模式

4.6.1 概述

  • 分离部件构造(由Builder来创建)和装配(Director组装)
  • 实现构建与装配解耦
  • 用户只需指定复杂对象类型就可得到最终对象,不需关注具体创建细节

4.6.2 结构

  • 抽象建造者类(Builder):规定实现复杂对象的创建,不涉及具体创建细节
  • 具体建造者类(ConcreteBuilder):实现Builder接口,完成复杂产品的各个部件具体创建方法,且在构造过程完成后提供产品实例
  • 产品类(Product):要创建的复杂对象
  • 指挥者类(Director):调用具体建造者类创建复杂对象的各个部分,只负责保证对象各部分完整创建或按某种顺序创建

4.6.3 特点

4.6.3.1 优点

  • 封装性好,有很好的稳定性
  • 客户端不必知道产品内部细节,将产品本身与产品创建过程解耦,使得相同创建过程可以创建不同产品对象
  • 可以更加精细控制产品创建过程
  • 容易扩展,有新需求可以实现一个新的建造者类来完成

4.6.3.2 缺点

所创建产品具有较多共同点,其组成部分相似,若产品之间差异性大不适合本模式

4.6.4 使用场景

本模式创建的复杂对象,其产品的各个部分经常面临剧烈的变化,但将它们组合一起的算法比较稳定,所以有以下场景

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

4.6.5 案例(组装自行车)

  • 抽象建造者
public abstract class Builder {  
//    声明Bike类型变量并进行赋值  
    protected Bike bike = new Bike();  
    public abstract void buildFrame();  
    public abstract void buildSeat();  
//    构建自行车方法  
    public abstract Bike createBike();  
}
  • 具体建造者
public class Mobike extends Builder{  
    @Override  
    public void buildFrame() {  
        bike.setFrame("碳纤维车架");  
    }  
    @Override  
    public void buildSeat() {  
        bike.setSeat("真皮车座");  
    }  
    @Override  
    public Bike createBike() {  
        return bike;  
    }  
}
public class OfoBike extends Builder{  
    @Override  
    public void buildFrame() {  
        bike.setFrame("铝合金框架");  
    }  
    @Override  
    public void buildSeat() {bike.setSeat("塑料车座");  
    }  
    @Override  
    public Bike createBike() {  
        return bike;  
    }  
}
  • 具体产品类
public class Bike {  
//    车架  
    private String frame;  
//    座位  
    private String seat;  
    public String getFrame() {  
        return frame;  
    }  
    public void setFrame(String frame) {  
        this.frame = frame;  
    }  
    public String getSeat() {  
        return seat;  
    }  
    public void setSeat(String seat) {  
        this.seat = seat;  
    }  
}
  • 指挥者
public class Director {  
//    声明builder类型变量  
    Builder builder ;  
    public Director(Builder builder) {  
        this.builder = builder;  
    }  
    public Bike bikeConstructor(){  
        builder.buildSeat();  
        builder.buildFrame();  
        return builder.createBike();  
    }  
}
  • 测试,结果![[Pasted image 20221230165431.png]]
public static void main(String[] args) {  
    Director director = new Director(new Mobike());  
    Bike bike = director.bikeConstructor();  
    System.out.println(bike.getFrame());  
    System.out.println(bike.getSeat());  
}
  • 类图![[Pasted image 20221230165731.png]]

4.6.6 扩展

4.6.6.1 问题

当类构造器需要传入较多参数或者有必选参数和非必选参数时,若创建实例则使代码可读性降低,容易发生错误

4.6.6.2 解决

  • 代码重构
  • 使用链式编程

4.6.6.3 案例(组装电脑)

  • 之前
public class Phone {  
    private String cpu;  
    private String screen;  
    private String memory;  
    private String mainBoard;  
    public Phone() {  
    }  
    public Phone(String cpu, String screen, String memory, String mainBoard) {  
        this.cpu = cpu;  
        this.screen = screen;  
        this.memory = memory;  
        this.mainBoard = mainBoard;  
    }  
    public String getCpu() {  
        return cpu;  
    }  
    public void setCpu(String cpu) {  
        this.cpu = cpu;  
    }  
    public String getScreen() {  
        return screen;  
    }  
    public void setScreen(String screen) {  
        this.screen = screen;  
    }  
    public String getMemory() {  
        return memory;  
    }  
    public void setMemory(String memory) {  
        this.memory = memory;  
    }  
    public String getMainBoard() {  
        return mainBoard;  
    }  
    public void setMainBoard(String mainBoard) {  
        this.mainBoard = mainBoard;  
    }  
    @Override  
    public String toString() {  
        return "Phone{" +  
                "cpu='" + cpu + '\'' +  
                ", screen='" + screen + '\'' +  
                ", memory='" + memory + '\'' +  
                ", mainBoard='" + mainBoard + '\'' +  
                '}';  
    }  
}
  • 之后
public class Phone {  
    private String cpu;  
    private String screen;  
    private String memory;  
    private String mainBoard;  
//    私有构造方法  
    private Phone(Builder builder){  
        this.cpu = builder.cpu;  
        this.screen = builder.screen;  
        this.memory = builder.memory;  
        this.mainBoard = builder.mainBoard;  
    }  
    @Override  
    public String toString() {  
        return "Phone{" +  
                "cpu='" + cpu + '\'' +  
                ", screen='" + screen + '\'' +  
                ", memory='" + memory + '\'' +  
                ", mainBoard='" + mainBoard + '\'' +  
                '}';  
    }  
//    内部类实现链式编程,解决参数传递问题  
    public static final class Builder{  
        private String cpu;  
        private String screen;  
        private String memory;  
        private String mainBoard;  
        public Builder cpu(String cpu){  
            this.cpu = cpu;  
            return this;        }  
        public Builder screen(String screen){  
            this.screen = screen;  
            return this;        }  
        public Builder memory(String memory){  
            this.memory = memory;  
            return this;        }  
        public Builder mainBoard(String mainBoard){  
            this.mainBoard = mainBoard;  
            return this;        }  
        public Phone build()  
        {  
            return new Phone(this);  
        }  
    }  
}
  • 测试,结果一样,但要是参数更多只用前者来写很容易出现错误,也较为复杂
public static void main(String[] args) {
	// 之前
//        Phone phone = new Phone("Intel","OL","金士顿","华硕");  
//        System.out.println(phone);
//         之后
//        创建手机对象,通过构造者对象获取手机对象  
        Phone phone = new Phone.Builder()  
                .cpu("Intel")  
                .screen("OL")  
                .memory("金士顿")  
                .mainBoard("华硕")  
                .build();  
        System.out.println(phone);  

    }

4.7 模式对比

4.7.1 工厂方法与建造者

  • 工厂方法:注重整体对象创建
  • 建造者:注重部件构建过程,意在一步一步精确按照顺序创建一个完整对象

4.7.2 抽象工厂与建造者

  • 抽象工厂:实现产品族的创建-----具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产
  • 建造者:按照指定图纸构建,通过零部件组装配件而产生一个新产品

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

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

相关文章

医药行业应用APS生产排产软件的必要性

高级计划与排程APS生产排产软件(advanced planning and scheduling) 是一个立足于整个企业生产活动的计算机系统。利用APS生产排产软件的管理手段和信息,企业可优化其从制定生产产量到管理最终产品的整个生产流程中的各个环节。利用实时、准确的数据,APS…

umi4 多环境配置改变

umi3 多环境我们可以根据脚本配置环境变量,然后配置不同的umirc 或者config 文件,从而达到配置多环境的效果。 问题描述 umi4 发布了,还是按照umi3 的配置了多环境, package.json 配置 了不同环境运行和编译脚本: co…

Netty进阶——粘包与半包(固定长度方式解决粘包问题)

目录一、固定长度方式解决粘包问题(代码示例)1.1、固定长度方式解决粘包问题的服务端代码示例1.2、固定长度方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、固定长度方式解决粘包问题&#x…

一零四六、Spark性能调优

本文分为四个部分,基本涵盖了所有Spark优化的点,面试和实际工作中必备。 《Spark性能优化:开发调优篇》《Spark性能优化:资源调优篇》《Spark性能优化:数据倾斜调优篇》《Spark性能优化:shuffle调优篇》Spa…

如何在C++ 中调用 Python

在一些场景下,C 通过调用脚本语言实现一些功能会比用C实现更加的方便。 这里要介绍的是pybind11,pybind11 借鉴了“前辈”Boost.Python,能够在 C 和 Python 之间自由转换,任意翻译两者的语言要素,比如把 C 的 vector …

0-1背包 完全背包 (模板)

目录 【模板】01背包_牛客题霸_牛客网 描述 输入描述: 输出描述: 【模板】完全背包_牛客题霸_牛客网 描述 输入描述: 输出描述: 【模板】01背包_牛客题霸_牛客网 描述 你有一个背包,最多能容纳的体积…

使用语义分割架构的文档扫描仪 DeepLabV3

0 介绍 地址:https://learnopencv.com/deep-learning-based-document-segmentation-using-semantic-segmentation-deeplabv3-on-custom-dataset/ 文档扫描是一个背景分割问题,可以使用多种方法解决。 它是计算机视觉广泛使用的应用程序之一。 在本文中,我们将文档扫描视为语…

从动态的角度分析DDR的时序结构

从整体上了解了DDR的特性和静态图,包括原理、管脚图等。那么本章就要从动态的角度来分析时序结构,包括read/write的整个过程到数据返回发生了什么。一,DRAM基本组成对于DRAM,其主要由行和列组成,每一个bit中都是由类似…

84、【栈与队列】leetcode ——1047. 删除字符串中的所有相邻重复项:栈+双指针解法(C++版本)

题目描述 原题链接:1047. 删除字符串中的所有相邻重复项 解题思路 一、栈顶匹配重复元素 本题需要删除重复且相邻元素,存入不重复元素。根据相邻特点,可采用栈进行实现。 当栈顶元素和遍历的字符串中的字符相同时,则将其弹栈。…

spring内置验证码kaptcha,baomidou使用详解

引入pom <dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId><version>1.1.0</version></dependency>application.yml 配置 kaptcha:height: 50width: 200content:length: 5s…

【Linux从入门到放弃】Linux编辑器——vim的使用

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《Linux从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; L…

TPM知识点集锦

1. 实体类型&#xff08;Entity Types&#xff09; &#xff08;1&#xff09;永久实体&#xff08;Permanent Entities&#xff09; 层级&#xff08;Hierarchies&#xff09;字典攻击锁定机制&#xff08;the dictionary attack lockout mechanism&#xff09;平台配置寄存…

Python安装torch(含torch和torchvision对应版本)

torch 、torchvision和python的对应版本如下&#xff1a; torch torchvision pythonmaster / nightlymaster / nightly>3.61.7.1 0.8.2>3.61.7.0 0.8.1>3.61.7.00.8.0>3.61.6.00.7.0>3.61.5.10.6.1>3.51.5.00.6.0>3.51.4.00.5.0 2.7, >3.5, <3.81…

HTC红外发射器基站红灯,死机,恢复出厂固件操作步骤

固件路径&#xff1a;C:\Program Files (x86)\Steam\steamapps\common\SteamVR\tools\lighthouse\firmware\lighthouse_tx\archive\htc_2.0 原厂244固件 找到以下两个文件 lighthouse_tx_htc_2_0-calibration-rescue-244.binlighthouse_tx_htc_2_0-244-2016-03-12.bin 1.在…

Python采集二手房源数据信息 基础版, 多线程版

前言 大家早好、午好、晚好吖 ❤ ~ 环境使用: Python 3.8 Pycharm 模块使用: requests >>> pip install requests 数据请求模块 parsel >>> pip install parsel 数据解析模块 re csv 内置模块 安装python第三方模块: win R 输入 cmd 点击确定, 输入…

基础算法(一)——快速排序

快速排序 介绍 快排是一种复杂度O(nlog(n)nlog(n)nlog(n))的排序算法&#xff0c;在极端情况下会退化为O(n2{n}^2n2)&#xff0c;但是它是一种原地算法&#xff0c;即不需要占据额外空间 原理是先在数列中取一个数x&#xff0c;这个数一般随机选取或是取中间值&#xff0c;然…

四、k8s实战入门

本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 1 namespace Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 默认情况下&#xff0c;kubernetes集群…

VuePress搭建文档网站遇到的一些坑点,中文路径,图片显示失败,打包白屏

VuePress搭建文档网站遇到的一些坑点 前言 本篇记录用VuePress搭建文档网站时碰到的一些坑点和解决方案 ★提高阅读体验★ &#x1f449; ♠一级标题 &#x1f448; &#x1f449; ♥二级标题 &#x1f448; &#x1f449; ♥ 三级标题 &#x1f448; &#x1f449; ♥…

HTML与CSS基础(六)—— CSS布局(浮动float)

目标能够使用 结构伪类选择器 在HTML中选择元素 能够说出 标准流 元素的布局特点 能够说出 浮动元素 的特点 能够使用浮动完成 小米模块布局案例 能够说出 清除浮动 的目的&#xff0c;并能够使用 清除浮动的方法一、结构伪类选择器目标&#xff1a;能够使用 结构伪类选择器 在…

MemPrompt: Memory-assisted Prompt Editing with User Feedback

Paper name MemPrompt: Memory-assisted Prompt Editing with User Feedback Paper Reading Note URL: https://arxiv.org/pdf/2201.06009.pdf TL;DR ACL 2022 Workshop CSRR 文章&#xff0c;MemPrompt 将用户对模型预测错误的反馈保存下来&#xff0c;之后遇到类似的问题…