当前位置: 首页 > news >正文

设计模式之建造者模式与原型模式

目录

建造者模式

简介

使用场景

优缺点

模式结构

实现

原型模式

简介

应用场景

优缺点

模式结构

实现


建造者模式

简介

        将复杂对象的构建与表示进行分离,使得同样的构建过程可以创建不同的表示。是一个将复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变分离,即产品的组成部分是不变的,但是每一部分都可以灵活选择。

使用场景

        1.当创建对象复杂时,可以将创建对象的步骤分离出去,使用建造者模式

        2.对于一些复杂的对象,如果对象的属性是由许多不同部分组成的,而这些部分需要按照一定的步骤进行创建,那么就可以使用建造者模式

        3.如果有许多相似的对象需要被创建,而且这些对象的创建过程相同,只是初始值不同,那么就可以使用建造者模式

        4.如果想要创建一个对象,但是对象的创建过程需要使用一些敏感信息,比如密码等,那么就可以使用建造者模式来保证这些敏感信息的安全性

优缺点

优点:

        1.封装性好,构建和表示分离

        2.扩展性好,各个具体的建造者相互独立,有利于系统解耦

        3.客户端不必知道产品内部的组成和细节,建造者可以对创建过程逐步细化,而不对其他模块产生任何影响,便于控制细节风险

缺点:

        1.产品的组成部分必须相同,限制了其使用范围

        2.产品内部发生变化,建造者也要修改,后期维护成本较大

模式结构

角色:

        产品角色:包含多个组成部分的复杂对象,由具体建造者来创建其各个零部件

        抽象建造者:包含创建产品各个子部件的抽象方法接口

        具体建造者:实现 Builder 接口,完成复杂产品的各个部件的具体创建方法

        指挥者:调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息

结构图:

实现

//产品角色:包含多个组成部件的复杂对象class Product {private String partA;private String partB;private String partC;
​public void setPartA(String partA) {this.partA = partA;}
​public void setPartB(String partB) {this.partB = partB;}
​public void setPartC(String partC) {this.partC = partC;}
​public void show() {//显示产品的特性}
}
​
//抽象建造者:包含创建产品各个子部件的抽象方法abstract class Builder {//创建产品对象protected Product product = new Product();public abstract void buildPartA();public abstract void buildPartB();public abstract void buildPartC();//返回产品对象public Product getResult() {return product;}
}//具体建造者:实现了抽象建造者接口。
public class ConcreteBuilder extends Builder {public void buildPartA() {product.setPartA("建造 PartA");}public void buildPartB() {product.setPartB("建造 PartB");}public void buildPartC() {product.setPartC("建造 PartC");}
}//指挥者:调用建造者中的方法完成复杂对象的创建class Director {private Builder builder;public Director(Builder builder) {this.builder = builder;}//产品构建与组装方法public Product construct() {builder.buildPartA();builder.buildPartB();builder.buildPartC();return builder.getResult();}
}//调用
public class Client {public static void main(String[] args) {Builder builder = new ConcreteBuilder();Director director = new Director(builder);Product product = director.construct();product.show();}
}

原型模式

简介

允许通过复制或克隆一个已存在的对象来创建一个新对象,而无需从头开始创建。这种模式在需要生成大量复制相似对象时特别有用。

应用场景

        1.创建新对象成本较大时

        2.系统要保存对象的状态,而对象的状态变化很小

        3.避免使用分层次的工厂类来创建分层次的对象

优缺点

优点:

        1.通过复制已有对象,而不是从头创建,节约了时间和资源

        2.如果对象包含多层嵌套,深复制会消耗太多资源;原型模式通过浅复制,可以避免

        3.可以避免通过构造方法复制时可能出现的错误

不足:

        1.增加了系统的复杂性,需要处理原始对象的复制和克隆操作

        2.复制对象,增加了内存使用量

        3.复制对象时,需确保所有的引用关系都正确的复制了

模式结构

角色:

        抽象原型类:声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类、接口和具体的实现类

        具体原型类:实现抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的克隆对象

        客户类:让一个原型对象克隆自己而创建一个新的对象,在客户类中只需要直接实例化或通过工厂方法的创建一个原型对象,再通过该对象的克隆方法即可获得多个相同的对象

实现

1.创建接口抽象类

public abstract class Shape implements Cloneable {private String id;protected String type;abstract void draw();public String getType(){return type;}public String getId() {return id;}public void setId(String id) {this.id = id;}public Object clone() {Object clone = null;try {clone = super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;}
}

2.拓展抽象类的实体类

public class Rectangle extends Shape {public Rectangle(){type = "Rectangle";}@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}public class Square extends Shape {public Square(){type = "Square";}@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}
}public class Circle extends Shape {public Circle(){type = "Circle";}@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}
}

3.创建一个类,从数据库获取实体类

import java.util.Hashtable;public class ShapeCache {private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>();public static Shape getShape(String shapeId) {Shape cachedShape = shapeMap.get(shapeId);return (Shape) cachedShape.clone();}// 对每种形状都运行数据库查询,并创建该形状// shapeMap.put(shapeKey, shape);// 例如,我们要添加三种形状public static void loadCache() {Circle circle = new Circle();circle.setId("1");shapeMap.put(circle.getId(),circle);Square square = new Square();square.setId("2");shapeMap.put(square.getId(),square);Rectangle rectangle = new Rectangle();rectangle.setId("3");shapeMap.put(rectangle.getId(),rectangle);}
}

4.进行克隆

public class PrototypePatternDemo {public static void main(String[] args) {ShapeCache.loadCache();Shape clonedShape = (Shape) ShapeCache.getShape("1");System.out.println("Shape : " + clonedShape.getType());        Shape clonedShape2 = (Shape) ShapeCache.getShape("2");System.out.println("Shape : " + clonedShape2.getType());        Shape clonedShape3 = (Shape) ShapeCache.getShape("3");System.out.println("Shape : " + clonedShape3.getType());        }
}

与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。

相关文章:

设计模式之建造者模式与原型模式

目录 建造者模式 简介 使用场景 优缺点 模式结构 实现 原型模式 简介 应用场景 优缺点 模式结构 实现 建造者模式 简介 将复杂对象的构建与表示进行分离&#xff0c;使得同样的构建过程可以创建不同的表示。是一个将复杂的对象分解为多个简单的对象&#xff0c;然…...

合并到pdf怎么合并?这个方法了解一下

在现代数字化时代&#xff0c;PDF(便携式文档格式)已成为最常用的文件格式之一。PDF文件的优点在于其跨平台兼容性和保持文档格式不变的能力。然而&#xff0c;在某些情况下&#xff0c;我们可能需要知道合并到pdf。无论是为了方便管理、共享或者其他目的&#xff0c;本文将介绍…...

vue使用jsencrypt实现rsa前端加密

实现 RSA 加密 介绍 vue 完成 rsa 加密传输&#xff0c;jsencrypt 实现参数的前端加密 1 安装 jsencrypt npm install jsencrypt2 编写 jsencrypt.js 在 utils 文件夹中新建 jsencrypt.js 文件&#xff0c;内容如下&#xff1a;注意点&#xff1a;一般公钥都是后端生成好的&a…...

微波系统中散射参量S、阻抗参量Z及导纳参量Y之间的关系及MATLAB验证

微波系统中散射参量S、阻抗参量Z及导纳参量Y之间的关系及MATLAB验证 用HFSS设计了一微波元件&#xff0c;仿真出了其散射参量S、阻抗参量Z及导纳参量Y&#xff0c;用MATLAB验证他们之间的关系 HFSS设计螺旋线圈 用HFSS设计了一个螺旋线圈&#xff0c;如上图所示。 进行仿真&…...

发收一体的2.4G射频合封芯片Y62G,内置九齐MCU

宇凡微2.4GHz发收一体合封芯片Y62G是一款高度集成的系统芯片&#xff0c;融合了2.4G芯片G350和微控制器&#xff08;MCU&#xff09;功能&#xff0c;为开发人员提供了更好的设计自由度和成本效益的解决方案。以下是Y62G芯片的主要特点和优势&#xff1a; 高度合封集成 Y62G芯…...

深度学习中epoch、batch、step、iteration等神经网络参数是什么意思?

epoch&#xff1a;表示将训练数据集中的所有样本都过一遍&#xff08;且仅过一遍&#xff09;的训练过程。在一个epoch中&#xff0c;训练算法会按照设定的顺序将所有样本输入模型进行前向传播、计算损失、反向传播和参数更新。一个epoch通常包含多个step。 batch&#xff1a;…...

『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段

『SpringBoot 源码分析』run() 方法执行流程&#xff1a;&#xff08;2&#xff09;刷新应用上下文-准备阶段 基于 2.2.9.RELEASE问题&#xff1a;当方法进行了注释标记之后&#xff0c;springboot 又是怎么注入到容器中并创建类呢&#xff1f; 首先创建测试主程序 package …...

WordPress Page Builder KingComposer 2.9.6 Open Redirection

WordPress Page Builder KingComposer 2.9.6 Open Redirection WordPress 插件 KingComposer 版本2.9.6 以及以前版本受到开放重定向漏洞的影响。该漏洞在packetstorm网站披露于2023年7月24日&#xff0c;除了该漏洞&#xff0c;该版本的插件还存在XSS攻击的漏洞风险 图1.来自…...

第五章:中国革命新道路

革命道路的艰难探索 1.国民党在全国统治的建立 南京国民政府的成立国民党政权的性质 2.土地革命战争的兴起 1. 大革命失败后的艰难环境 2. 开启武装反抗国民党统治的斗争&#xff1a; 南昌起义&#xff1a;共产党独立领导的革命战争&#xff0c;创建人民军队和武装夺取政权…...

PMP-沟通管理的重要性

一、什么是项目沟通管理 项目沟通管理包括通过开发工件&#xff0c;以及执行用于有效交换信息的各种活动&#xff0c;来确保项目及其相关方的信息需求得以满足的各个过程。项目沟通管理由两个部分组成&#xff1a;第一部分是制定策略&#xff0c;确保沟通对相关方行之有效&…...

【Sentinel】降级源码:插槽DegradeSlot与断路器的实现

文章目录 1、实现原理2、DegradeSlot类3、CircuitBreaker4、触发断路器 1、实现原理 Sentinel的降级是基于状态机来实现的&#xff1a; 2、DegradeSlot类 熔断降级的逻辑在DegradeSlot类中实现&#xff0c;核心API&#xff1a; Override public void entry(Context context,…...

【Apollo】开启Apollo之旅:让自动驾驶如此简单

前言 Apollo 是百度公司推出的自动驾驶平台。它是一个综合性的自动驾驶解决方案&#xff0c;提供了包括感知、决策、规划和控制等核心功能&#xff0c;以及地图、定位、仿真、数据管理等配套工具。 文章目录 前言Apollo 的发展历程Apollo 8.0新特性软件包管理感知框架工具链小…...

maven搭建spring项目

前提 安装jdk 安装maven 安装eclipse 创建maven项目 搭建spring项目 pom.xml <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.4.RELEASE</version> </dependency&…...

Java“牵手”阿里巴巴商品详情数据,阿里巴巴商品详情API接口,阿里巴巴国际站API接口申请指南

阿里巴巴平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取阿里巴巴商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xf…...

MYSQL调优之思路----sql语句和索引调优

MySQL数据库性能优化包括综合多方面因素&#xff0c;应根据实际的业务情况制定科学、合理的调优方案进行测试调优 文章目录 MySQL性能优化1 优化介绍1.2 优化要考虑的问题2.1 优化可能带来的问题2.2 优化的需求2.3 优化由谁参与2.4 优化的方向2.5 优化的维度 1.2数据库使用优化…...

论文阅读_变分自编码器_VAE

英文名称: Auto-Encoding Variational Bayes 中文名称: 自编码变分贝叶斯 论文地址: http://arxiv.org/abs/1312.6114 时间: 2013 作者: Diederik P. Kingma, 阿姆斯特丹大学 引用量: 24840 1 读后感 VAE 变分自编码&#xff08;Variational Autoencoder&#xff09;是一种生…...

springboot整合elasticsearch使用案例

引入依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> 添加注入 import org.apache.http.HttpHost; import org.elasticsearch.client.Res…...

Unity制作下雨中的地面效果

Unity引擎制作下雨效果 大家好&#xff0c;我是阿赵。   之前介绍了Unity引擎里面通过UV偏移做序列帧动画的做法&#xff0c;这里再介绍一个进阶的用法&#xff0c;模拟地面下雨的雨点效果。 一、原理 最基本的原理&#xff0c;还是基于这个序列帧动画的做法。不过这里做一点…...

windows从0搭建python3开发环境与开发工具

文章目录 一、python3下载安装1、下载2、安装3、测试 二、安装VS Code1、安装2、安装python插件3、测试 三、pip命令的使用1、基本命令2、修改pip下载源 一、python3下载安装 1、下载 打开 WEB 浏览器访问 https://www.python.org/downloads/windows/ &#xff0c;一般就下载…...

centos中得一些命令 记录

redis命令 链接redis数据库的命令 redis-cli如果 Redis 服务器在不同的主机或端口上运行&#xff0c;你需要提供相应的主机和端口信息。例如&#xff1a; redis-cli -h <hostname> -p <port>连接成功后&#xff0c;你将看到一个类似于以下的提示符&#xff0c;表…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...