设计模式之生成器(建造者)模式笔记

news2024/10/6 12:29:04

设计模式之建造者模式笔记

  • 说明
  • Builder(生成器)
  • 目录
  • UML生成器(建造者)模式示例类图
    • 自行车类
    • 建造者抽象类
    • 摩拜单车对象类
    • 小黄车单车对象类
    • 指挥者类
    • 测试类
    • 优缺点
  • 模式扩展
    • 手机类
    • 测试类

说明

记录下学习设计模式-生成器(也叫建造者)模式的写法。

Builder(生成器)

意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
结构:
在这里插入图片描述

其中:

  • Builder为创建一个Product对象的各个部件指定抽象接口。
  • ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。
  • Director构造一个使用Builder接口的对象。
  • Product表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成组件的类,包括将这些组件装配成最终产品的接口。

适用性:

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

目录

在这里插入图片描述

UML生成器(建造者)模式示例类图

在这里插入图片描述

以该UML类图实现生成器(建造者)模式示例。

自行车类

package com.example.deesign_patterns.builder.demo1;

//产品对象,自行车类
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;
    }
}

建造者抽象类

package com.example.deesign_patterns.builder.demo1;

public abstract class Builder {

    //声明Bike类型的变量,并进行赋值
    protected Bike bike=new Bike();

    //构造车架方法
    public abstract void buildFrame();

    //构造车座方法
    public abstract void buildSeat();

    //构造自行车的方法
    public abstract Bike createBike();
}

摩拜单车对象类

package com.example.deesign_patterns.builder.demo1;

//具体的构建者,用来构建摩拜单车对象
public class MobileBuilder extends Builder{

    @Override
    public void buildFrame() {
        bike.setFrame("碳纤维车架");
    }

    @Override
    public void buildSeat() {
        bike.setSeat("真皮车座");
    }

    @Override
    public Bike createBike() {
        return bike;
    }
}

小黄车单车对象类

package com.example.deesign_patterns.builder.demo1;

//具体的构建者,用来构建小黄车单车对象
public class OfoBuilder extends Builder{

    @Override
    public void buildFrame() {
        bike.setFrame("铝合金车架");
    }

    @Override
    public void buildSeat() {
        bike.setSeat("橡胶车座");
    }

    @Override
    public Bike createBike() {
        return bike;
    }
}

指挥者类

package com.example.deesign_patterns.builder.demo1;

//指挥者类
public class Director {

    //声明builder类型的变量
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    //组装自行车的功能
    public Bike construct(){
        builder.buildFrame();
        builder.buildSeat();
        return builder.createBike();
    }
}

测试类

package com.example.deesign_patterns.builder.demo1;

//测试类
public class Client {

    public static void main(String[] args) {
        //创建指挥者对象
        Director director=new Director(new MobileBuilder());
        //让指挥者指挥组装自行车
        Bike bike = director.construct();
        //如果正常打印出车架和车座,说明已经组装好
        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }
}


在这里插入图片描述

优缺点

优点:

  • 生成器(建造者)模式的封装性很好。使用生成器(建造者)模式可以有效的封装变化,在使用生成器(建造者)模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在指挥者类中对整体而言可以取得比较好的稳定性。
  • 在生成器(建造者)模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  • 生成器(建造者)模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。

缺点:

  • 生成器(建造者)模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用生成器(建造者)模式,因此其使用范围受到一定的限制。

模式扩展

生成器(建造者)模式除了上面的用途外,在开发中还有一个常用的使用方式,就是当一个类的构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用生成器(建造者)模式进行重构。

手机类

package com.example.deesign_patterns.builder.demo2;

//手机类
public class Phone {

    private String cpu;//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;//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;
        }

        //使用构建者创建Phone对象
        public Phone build(){
            return new Phone(this);
        }
    }
}

测试类

package com.example.deesign_patterns.builder.demo2;

//测试类
public class Client {

    public static void main(String[] args) {
        //创建手机对象,通过构建者对象获取手机对象(链式编程设置值,感觉和stream流相似)
        Phone phone=new Phone.Builder()
                .cpu("intel")
                .screen("三星屏幕")
                .memory("金士顿内存条")
                .mainBoard("华硕主板")
                .build();
        //如果类里面有toString()方法,会自动去调用,没有写则打印对象地址
        System.out.println(phone);
    }
}

在这里插入图片描述

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

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

相关文章

监控中的计算机科学

文章目录 一、前言二、监控分类2.1 模拟摄像头2.1 数字摄像头 三、监控系统四、后端产品4.1 硬盘录像机4.2 视频矩阵4.3 控制设备4.4 显示设备 五、传输端5.1 光纤视频线5.1.2 单模光纤5.1.3 多模光纤5.1.4 光端机 5.1 双绞线 六、畅享 一、前言 布林肯访华,黑我们…

Redis6之事务与锁

事务 Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 Redis事务的主要作用就是串联多个命令防止别的命令插队。 命令 1、开启事务:multi 2、执行事…

STM32 RGB屏幕

使用ST的HAL库进行开发,RGB屏幕是480*272的4.3寸LCD,由于驱动RGB屏幕需要较多的内存, 所以使用了外部SDRAM,内存是32M字节,关于SDRAM的驱动本文不进行讨论。 RGB屏幕常用的像素格式有:ARGB8888、RGB888、…

Vue----Vue项目的目录结构

【原文链接】Vue----Vue项目的目录结构 Vue 项目的目录结构 VUE项目的目录结构如下所示 .vscode VSCode工具的配置文件,和VUE项目没有什么关系 node_modules VUE项目运行依赖文件,通过npm install 安装的文件即存放在此文件夹 public 资源文件夹&am…

【现代密码学】(网安)期末复习笔记

现代密码学 【考后感悟】还是得注重简答题,需每个密码算法都要有所了解(有些难的可以不用了解完整算法过程,估计考不上?),并对几个重要密码算法(重点下面会讲)着重复习(会…

部署kubernets v1.27.3集群

本文将演示如何使用kubeadm快速部署一个Kubernetes v1.27.1集群,并会简单说明如何在集群上部署nginx容器 主机环境预设 本示例中的Kubernetes集群部署将基于以下环境进行。 OS: Ubuntu 20.04 Kubernetes:v1.27.3 Container Runtime: Docker CE 23.0.…

【并发编程】深入探索AQS

文章目录 一、AQS 介绍二、通过ReentrantLock分析AQS的实现2.1、获取锁流程2.2、获取锁源码分析2.2.1、acquire2.2.2、tryAcquire2.2.3、addWaiter2.2.4、acquireQueued2.2.5、shouldParkAfterFailedAcquire 2.3、解锁源码分析2.3.1、unlock2.3.2、release2.3.3、tryRelease2.3…

实验篇(7.2) 17. 站对站安全隧道 - FortiGate作为SSL客户端(SSL) ❀ 远程访问

【简介】虽然常用的站到站的连接用的是IPsec VPN,但是在某些特殊情况下,UDP500或4500端口被阻断,IPsec VPN无法连接,那么还有其它办法实现站到站的连接吗?SSL VPN也可以的。 实验要求与环境 OldMei集团深圳总部部署了域…

NodeJS File Upload⑩

文章目录 ✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘前言文件上传 后端接口 Form表单上传 Axios前后端分离上传 实现效果演示 记录 读取图片文件总结 ✨文章有误请指正,如果觉得对你有用&a…

RK3568平台开发系列讲解(外设篇)四线风扇驱动实验

🚀返回专栏总目录 文章目录 一、硬件连接二、原理图分析三、驱动适配3.1、内核配置3.2、修改设备树3.3、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解四线风扇的使用。 一、硬件连接 风扇模块如下所示,黑线是负,红线是正,黄线是测速,蓝线是…

算法——字符串匹配算法——BM(Boyer-Moore) 算法

字符串匹配算法——BM (Boyer-Moore) 算法 概述场景一 坏字符场景且模式串中没有匹配字符场景二 坏字符场景且模式串中有匹配字符场景三 好后缀场景且模式串中没有匹配字符场景四 好后缀场景且模式串中有匹配字符场景五 好后缀场景且模式串中有匹配子串后…

EfficientDet-pytorch目标检测训练

目录 1. EfficientDet-pytorch版本代码下载 2.数据集准备 2.1数据集格式 2.2 定义自己数据集的yml文件 3. 训练配置 4.模型评估 5.测试模型性能 1. EfficientDet-pytorch版本代码下载 GitHub - zylo117/Yet-Another-EfficientDet-Pytorch: The pytorch re-implement…

chatgpt赋能python:Python提取指定数据的方法与技巧

Python提取指定数据的方法与技巧 在SEO优化中,数据的提取和分析是非常重要的环节之一。而Python具有方便易用的数据处理能力,成为了SEO优化工程师们的重要工具之一。本文将介绍Python中提取指定数据的方法与技巧,以及实现的具体案例。 数据…

python:使用Scikit-image库进行单波段遥感图像颜色直方图特征提取(histogram)

作者:CSDN @ _养乐多_ 本文记录了使用Scikit-image库对单波段遥感图像做颜色直方图特征提取的代码。 文章目录 一、颜色直方图特征详解二、代码一、颜色直方图特征详解 颜色直方图是一种用于描述图像中颜色分布的特征表示方法。它将图像中每个像素的颜色值作为输入,统计并显…

Java 基础进阶篇(十七):反射概述及获取对象的方式

文章目录 一、反射概述二、反射获取类对象三、反射获取构造器对象四、反射获取成员变量对象五、反射获取方法对象六、 反射的作用6.1 绕过编译阶段为集合添加数据6.2 通用框架的底层原理 一、反射概述 反射是指对于任何一个Class类,在 “运行的时候”,不…

PHP实战开发23-PHP结合Nginx获取用户真实IP地址

文章目录 一、前言二、关于用户IP的背景知识2.1 HTTP请求2.2 HTTP代理服务器2.3 X-Forwarded-For头部 三、代码实现3.1 Nginx配置3.2 PHP代码处理 总结 一、前言 本文已收录于PHP全栈系列专栏:PHP快速入门与实战 在Web应用程序中,IP地址是常见的数据项…

Flink 学习四 Flink 基础架构

Flink 学习四 Flink 基础架构&算子链&槽位 文章大部分数据来源 : https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/concepts/flink-architecture/ Flink 是一个分布式系统,需要有效的分配和管理计算资源才可以执行流式程序; 集成了常见的资源管理…

chatgpt赋能python:Python简介

Python简介 Python是一种高级编程语言,具有易读性和简洁性的特点。它被广泛使用于Web开发、数据科学、人工智能、机器学习和自动化测试等领域。Python也是一种非常适合新手学习编程的语言。 在本篇文章中,我们将讨论如何使用Python提取指定内容以进行S…

【BMS】电池包硬件方案选型指南

🔋电池包硬件方案选型指南🔋 BMS硬件系统需求主要包括:测温模块、测流模块、测压模块、系统电源、保护电路、故障检测电路,本文阐述各个功能模块在不同场景下的电池包硬件系统方案选择。 一、测温 NTC(热敏电阻) 电池包测温一般包括表皮温度、内部温度、PCB温度(极片布…

[自定义组件]微信小程序自定义组件实现缩略图和原图分离及可缩放效果

目录 目标及基础环境背景 实现原理左右滑动缩放图片菜单 开发实现自定义组件wxml组件结构wxss 样式控制js定义属性及回调json声明为组件 使用添加组件声明及地址声明为全局组件(也可声明为局部)声明为全局组件(也可以声明为全局组件)使用组件 效果展示 附…