【设计模式】原型模式与建造者模式
原型模式
原型模式是指通过原型实例指定创建对象的种类,然后通过拷贝的方式创建新的对象。属于创建型模式
原型模式的核心在于拷贝原型对象,主要用于对对象的复制。当你需要通过一大段get/set方法去构建对象的时候,就可以考虑使用原型模式了 我们经常使用的JSON.parseObject() 也是一种原型模式
其类图如下所示
1.原型类IPrototype: 定义一个clone的接口方法,
2.子类: 需要被拷贝的对象
3.Client : 调用clone方法拷贝对象

实现
public interface IPrototype<T> {T clone();
}
public class PrototypeA implements IPrototype<PrototypeA>{private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic PrototypeA clone() {PrototypeA prototypeA = new PrototypeA();prototypeA.setAge(this.age);prototypeA.setName(this.name);return prototypeA;}
}
JDK已经提供了一个Cloneable接口,帮我们实现了拷贝的逻辑
public class PrototypeB implements Cloneable{private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public PrototypeB clone() {try {return (PrototypeB) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}
}
深克隆和浅克隆
前面虽然实现了对原型对象的克隆,但它只是复制了值类型数据,对于引用类型对象并没有做一个完整的拷贝,只是简单复制了引用的地址,这会导致克隆后的对象和原型对象之间的数据相互干扰,明显不符合预期(也就是浅克隆)
我们可以用序列化的方式实现深克隆
public class PrototypeB implements Cloneable, Serializable {private String name;private Integer age;private List<String> friends;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public PrototypeB clone() {try {return (PrototypeB) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}public PrototypeB deepClone() {try {//输出流ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);return (PrototypeB) ois.readObject();} catch (Exception e) {throw new RuntimeException(e);}}
}
可以看出克隆会破坏单例模式,一般情形下我们的单例类都不会实现Cloneable接口,如果需要实现该接口,可以重写clone方法让其在克隆时返回唯一的实例对象
建造者模式
建造者模式: 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
属于创建型模式
使用场景:
- 适合于创建对象需要很多复杂步骤的场景,将复杂对象的创建和使用分离开来
- 适合于有多个不同的创建步骤,需要根据不同场景选择不同的顺序
该设计模式中,有以下几个角色:
- Product产品:表示要被创建的对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
- Builder: 建造者的抽象类,由子类实现其建造过程
- ConcreteBuilder:实现Builder的接口以创建满足条件的对象
- Director:指导者,由其决定创建复杂对象的步骤
举一个例子: 我手头上有三个任务,我需要根据不同的条件设置需要执行的任务(建造者模式一般采用链式的写法)
public class Product {private String task1;private String task2;private String task3;public String getTask1() {return task1;}public void setTask1(String task1) {this.task1 = task1;}public String getTask2() {return task2;}public void setTask2(String task2) {this.task2 = task2;}public String getTask3() {return task3;}public void setTask3(String task3) {this.task3 = task3;}@Overridepublic String toString() {return "Product{" +"task1='" + task1 + '\'' +", task2='" + task2 + '\'' +", task3='" + task3 + '\'' +'}';}
}
public interface IBuilder<T> {T build();IBuilder buildTask1(String task);IBuilder buildTask2(String task);IBuilder buildTask3(String task);}
public class BuilderA implements IBuilder<Product>{private Product product = null;public BuilderA() {this.product = new Product();}public BuilderA buildTask1(String task) {product.setTask1(task);return this;}public BuilderA buildTask2(String task) {product.setTask2(task);return this;}public BuilderA buildTask3(String task) {product.setTask3(task);return this;}@Overridepublic Product build() {return this.product;}
}
public class Director {public Product build(IBuilder builder) {builder.buildTask1("任务1");builder.buildTask2("任务2");return (Product) builder.build();}}
public class Client {public static void main(String[] args) {Director director = new Director();Product product = director.build(new BuilderA());System.out.println(product);}}
如果被建造的对象只有一个的话,可以省略抽象的Builder和Director,让ConcreteBuilder自己扮演指导者和建造者双重角色,甚至ConcreteBuilder也可以在Product里实现。
建造者模式和工厂模式的区别
- 建造者模式更加关注于创建的步骤顺序,而工厂模式更关注于创建的结果-对象
- 建造者模式使用不同的步骤创建,最后创建出来的对象不一样,工厂模式创建出来的都是一样的(可以理解为工厂都是批发的)
相关文章:
【设计模式】原型模式与建造者模式
原型模式 原型模式是指通过原型实例指定创建对象的种类,然后通过拷贝的方式创建新的对象。属于创建型模式 原型模式的核心在于拷贝原型对象,主要用于对对象的复制。当你需要通过一大段get/set方法去构建对象的时候,就可以考虑使用原型模式了…...
QT之Http请求
今天我们介绍一下QT的http请求,这里有post和get两种方式 一、post请求方式:参数分为网址和具体请求值两个部分,有时候还需要设置头信息,看具体情况定 1 void MainWindow::sendPostRequest()2 {3 QNetworkAccessManager *m_pH…...
何谓dB , dB怎么理解?
dB 是什么单位 ?愈低愈好吗?对于声频 ( 声学及电子声学 ) 方面的单位,它是以分贝(decibel ,dB ) 来做结果的。斯多里一生专注于科学,1876 发明电话,我们都知道贝尔发明了电话,然而重要的是,他发现我们人类耳朵对声音…...
【数据聚类|深度聚类】Unsupervised Deep Embedding for Clustering Analysis(DEC)论文研读
DEC算法由两部分组成 第一部分会预训练一个SDAE模型;第二部分选取SDAE模型中的Encoder部分,加入聚类层,然后最小化KL散度进行训练聚类Absratct 提出了一种利用深度神经网络同时进行表征学习和聚类分配的方法,称之为深度嵌入聚类。该方法学习从数据空间到低纬空间的映射,并…...
Nuxt.js项目开发过程遇到的问题以及对Nuxt.js的学习与总结
文章目录📋前言💻Nuxtjs3快速了解🎯nuxtjs是什么?官网是这样介绍它的。🎯关于nuxtjs的SSR开发🧩SSR应用场景🧩nuxtjs的特性💻nuxtjs的初始目录结构🎯关于各个目录的解释&…...
JavaSE:异常机制
异常概念异常发生的原因用户输入非法数据要打开的文件不存在网络中断/JVM内存溢出(JVM是JRE的一部分。它是一个虚构出来的计算机)除0、非法参数等三种类型的异常,用以理解异常检查性异常【otherException】:程序员无法预见的&…...
Go mockito 使用说明 (github/mockey)
GitHub - bytedance/mockey: a simple and easy-to-use golang mock library Go mockito 是什么? mockey是一个简单易用的golang mock库,可以快速方便的mock函数和变量。目前广泛应用于字节跳动服务的单元测试编写。底层是monkey patch,通过在运行时重…...
Spring Boot+Vue前后端分离项目练习01之网盘项目的搭建
1.前期设计 一般看来,网盘系统主要实体包括:用户、存储信息、用户文件、文件、回收文件等基本功能点。 各实体对应的表结构如下所示: 表名:user(用户表) 字段名属性说明userIdbigint主键usernamevarcha…...
超详细MySQL(免安装版)安装与配置
一、MySQL下载 首先打开MySQL官网,官网首页地址为 MySQL官网首页地址 进入官网后如下图所示,点击DOWNLOADS进入下载页面 下滑页面找到MySQL Community(GPL)Downloads>>并点击 接下来点击MySQL Community Server 若想要安…...
STM32F1,F4,L1系列禁止JTAG和SW引脚方法
STM32F1系列 程序中在使用到JTAG、SWD的某个IO 时,需要禁用掉相关调试方法后,再配置相应的IO方式。在需要相应的接口配置前使用这些代码。 对于F1系列,调用函数进行专门的禁止。 标准库配置方式: RCC_APB2PeriphClockCmd(RCC_A…...
NVIDIA CUDA初级教程视频学习笔记1
周斌老师 课程链接: 目录第一课内容生态环境第一课 CPU体系架构的概述什么是CPU指令存储器架构CPU内部的并行性第一课 预修课程: Cuda c programming guide 参考内容 1,2,3查找一下。 内容 CPU体系架构概述 并行程序设计概述 CUDA开发环境…...
CEC2005:星雀优化算法(Nutcracker optimizer algorithm,NOA)求解CEC2005(提供MATLAB代码)
一、星雀优化算法NOA 星雀优化算法(Nutcracker optimizer algorithm,NOA)由Mohamed Abdel-Basset等人于2023年提出,该算法模拟星雀的两种行为,即:在夏秋季节收集并储存食物,在春冬季节搜索食物的存储位置。 星鸦单独或成对活动&…...
工作实战之密码防重放攻击
目录 前言 一、登录认证密码加密 二、bcrypt加密密码不一样,匹配原理 1.程序运行现象 2.原理解释 三、密码防重放 总结 前言 密码重放攻击:请求被攻击者获取,并重新发送给认证服务器,从而达到认证通过的目的 一、登录认证密…...
如何编写测试用例?
编写测试用例流程 1、确定测试目标:首先,需要明确测试目标,即测试人员需要测试什么,这有助于测试人员了解需要测试哪些方面,以及如何测试。 2、识别测试场景:在确定测试目标后,测试人员需要识…...
5.排序算法之二:选择排序
选择排序(select sort)在无序列表中,把无序列表分成有序区(刚开始有序区元素个数为0)和无序区(刚开始无序区元素个数为n),循环n-1趟,每一趟找到最小或最大的那个元素&…...
Ubuntu18系统安装:node及node版本管理工具nvm部署前端项目
注意在安装之前先安装好Git 如何在Ubuntu 上安装Git与入门教程_ubuntu安装git_飞鹰雪菲的博客-CSDN博客 1、把nvm远程镜像克隆到指定目录 git clone https://gitee.com/mirrors/nvm 1.1在终端指定的文件夹下 drciZwz91oq31508figapkas0Z:~/qiang/tools$ git clone https://…...
统计学 假设检验
文章目录假设检验假设检验的基本原理提出假设作出决策表述决策结果一个总体参数的检验总体均值的检验总体比例的检验总体方差的检验两个总体参数的检验两个总体均值之差的检验两个总体比例之差的检验两个总体方差比的检验总体分布的检验正态性检验的图示法Shapiro-Wilk 和 K-S …...
【C++】哈希
哈希一、unordered系列关联式容器二、哈希原理2.1 哈希映射2.2 哈希冲突2.2.1 闭散列—开放地址法2.2.2 代码实现2.2.3 开散列—拉链法2.2.4 代码实现三、哈希封装unordered_map/unordered_set3.1 基本框架3.2 迭代器实现3.2.3 operator*和operator->和operator!3.2.4 opera…...
「TCG 规范解读」PC 平台相关规范(3)
可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alli…...
这篇教你搞定Android内存优化分析总结
一、内存优化概念1.1 为什么要做内存优化?内存优化一直是一个很重要但却缺乏关注的点,内存作为程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&…...
彻底解决Windows 11系统稳定性问题:ExplorerPatcher核心技术解析与实战指南
彻底解决Windows 11系统稳定性问题:ExplorerPatcher核心技术解析与实战指南 【免费下载链接】ExplorerPatcher 提升Windows操作系统下的工作环境 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher 当你的Windows 11系统频繁出现界面无响应…...
解析 C++ 中的‘生存期保护’:利用生命周期注解规避 99% 的悬挂指针风险
解析 C 中的“生存期保护”:利用生命周期注解规避 99% 的悬挂指针风险尊敬的各位开发者,各位对 C 内存安全孜孜不倦的探索者们,大家好!在 C 的广阔世界中,指针和引用以其强大的能力,赋予了我们对内存的直接…...
5个核心功能提升音频处理效率:AsrTools语音转文字工具用户指南
5个核心功能提升音频处理效率:AsrTools语音转文字工具用户指南 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into a…...
零基础学编程:借助快马与claude code生成交互式代码示例入门javascript
最近刚开始学习JavaScript,发现数组操作是编程中最基础也最常用的部分。作为一个完全零基础的小白,我尝试用InsCode(快马)平台结合Claude Code来学习这个知识点,整个过程比想象中顺利很多。这里记录下我的学习过程,希望能帮到同样…...
三三复制系统模式介绍
三三复制系统模式介绍:从底层逻辑到合规落地在社交电商与团队裂变领域,三三复制系统凭借其低门槛、高稳定性的特点,成为企业实现用户快速增长与业绩倍增的重要工具。不同于传统多级分销的复杂层级,三三复制系统以“三”为核心基数…...
百川2-13B-4bits量化版精度测试:OpenClaw自动化任务准确率对比
百川2-13B-4bits量化版精度测试:OpenClaw自动化任务准确率对比 1. 测试背景与实验设计 上周在部署OpenClaw自动化工作流时,我遇到了一个现实问题:本地显卡只有12GB显存,跑不动原版13B模型。于是尝试了百川2-13B的4bits量化版本&…...
咱们今天来唠唠机器人轨迹规划那点事儿。不少小伙伴在玩机械臂的时候总会遇到关节空间和笛卡尔空间轨迹规划的抉择困难症,这俩货到底有什么区别?直接上硬核代码
matlab笛卡尔空间和关节空间轨迹规划 关节空间机器臂多项式轨迹规划定做,353和333多项式轨迹规划和优化关节空间规划有个大杀器——多项式插值。比如要让机械臂从A点平滑运动到B点,咱们可以玩三次多项式(3-3-3)或者五次多项式&…...
3大核心功能:让iOS推送调试效率提升10倍的SmartPush工具全解析
3大核心功能:让iOS推送调试效率提升10倍的SmartPush工具全解析 【免费下载链接】SmartPush SmartPush,一款iOS苹果远程推送测试程序,Mac OS下的APNS工具APP,iOS Push Notification Debug App 项目地址: https://gitcode.com/gh_mirrors/smar/SmartPush 一、问…...
MQTT通信中的QoS级别详解:SpringBoot如何选择最适合的传输质量?
MQTT通信中的QoS级别详解:SpringBoot如何选择最适合的传输质量? 在物联网和分布式系统架构中,消息传输的可靠性往往直接关系到业务逻辑的正确性。MQTT协议作为轻量级发布/订阅模式的通信标准,其QoS(服务质量࿰…...
Qwen3-14B-AWQ模型效果深度评测:在算法题求解上的表现
Qwen3-14B-AWQ模型效果深度评测:在算法题求解上的表现 1. 评测背景与模型简介 在AI技术快速发展的今天,大语言模型在代码生成和算法解题领域展现出越来越强的能力。Qwen3-14B-Int4-AWQ作为通义千问系列的最新量化版本,在保持较高推理能力的…...
