设计模式--原型模式和建造者模式

原型模式

原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些这些原型创建新的对象,属于创建型模式。(对不通过new关键字,而是通过对象拷贝来实现创建对象的模式称为原型模式)。

原型模式的核心在于拷贝原型对象。以系统中已经存在的一个对象为原型,直接基于内存二进制流进行拷贝,无需再经历耗时的对象初始化过程(不调用构造函数)。

原型模式适用以下场景:

  1. 类初始化消耗资源比较多
  2. new产生的一个对象需要非常繁琐的过程
  3. 构造函数比较复杂
  4. 循环体中产生大量的对象

 一个标准的原型模式代码:

interface IPrototype<T>{T clone();
}class ConcretePrototype implements IPrototype{private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic ConcretePrototype clone() {ConcretePrototype concretePrototype = new ConcretePrototype();concretePrototype.setAge(this.age);concretePrototype.setName(this.name);return concretePrototype;}@Overridepublic String toString() {return "ConcretePrototype{" +"age=" + age +", name='" + name + '\'' +'}';}
}public class Test {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype();prototype.setAge(18);prototype.setName("Tom");System.out.println(prototype);ConcretePrototype cloneType = prototype.clone();System.out.println(cloneType);}
}

上面的复制过程是我们自己完成的,另外,JDK已经帮我们实现了一个现成的API,我们只需要实现Cloneable接口即可。

class ConcretePrototype implements Cloneable{private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic ConcretePrototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}@Overridepublic String toString() {return "ConcretePrototype{" +"age=" + age +", name='" + name + '\'' +'}';}
}

然而,复制后的克隆对象是的成员复制的不是值,而是引用的地址。如果我们修改任意一个对象中的属性值,prototype和cloneType的属性值都会改变。这就是我们常说的浅克隆。只是完整复制了值数据类型,没有赋值引用对象(所有的引用对象仍然指向原来的对象)。

使用序列化实现深度克隆

class ConcretePrototype implements Cloneable, Serializable {private int age;private String name;private List<String> hobbies;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getHobbies() {return hobbies;}public void setHobbies(List<String> hobbies) {this.hobbies = hobbies;}@Overridepublic ConcretePrototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}public ConcretePrototype deepClone(){try{ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (ConcretePrototype) ois.readObject();}catch (Exception e){e.printStackTrace();return null;}}@Overridepublic String toString() {return "ConcretePrototype{" +"age=" + age +", name='" + name + '\'' +", hobbies=" + hobbies +'}';}
}public class Test {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype();prototype.setAge(18);prototype.setName("Tom");List<String> hobbies = new ArrayList<>();hobbies.add("Math");hobbies.add("baseball");prototype.setHobbies(hobbies);System.out.println(prototype);ConcretePrototype cloneType = prototype.deepClone();System.out.println(cloneType);System.out.println(prototype.getHobbies());System.out.println(cloneType.getHobbies());System.out.println(prototype.getHobbies() == cloneType.getHobbies());}
}

克隆破坏单例模式

如果我们克隆的目标对象是单例对象,那么深克隆就会破坏单例。为了防止克隆破坏单例,只要禁止深克隆就行。

一种是不实现Cloneable接口,重新clone方法,在clone方法中返回单例对象即可。

原型模式的优缺点:

优点:

1、性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能提升许多。

2、可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其保存起来,简化了创建对象的过程。

缺点:

1、需要为每一个类配置一个克隆方法。

2、克隆方法位于类的内部,当对已有的类进行改造的时候,需要修改代码,违反了开闭原则。

3、实现深度克隆需要编写较为复杂的代码。

建造者模式

建造者模式(Builder Pattern)是将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。建造者模式适用于创建对象需要很多步骤,但步骤的顺序不一定固定。如果一个对象有非常复杂的内部结构(很多属性),可以将复杂对象的创建和使用进行分离。

建造者模式的基本写法:

import lombok.Data;@Data
class Course{private String name;private String ppt;private String video;
} class CourseBuilder{private Course course = new Course();public void addName(String name){course.setName(name);}public void addPpt(String ppt){course.setPpt(ppt);}public void addVideo(String video){course.setVideo(video);}public Course build(){return this.course;}
}public class Test {public static void main(String[] args) {CourseBuilder builder = new CourseBuilder();builder.addName("设计模式");builder.addPpt("【ppt】");builder.addVideo("【视频】");Course course = builder.build();System.out.println(course);}
}

建造者模式的链式写法:

import lombok.Data;class CourseBuilder{@Datapublic class Course{private String name;private String ppt;private String video;}private Course course = new Course();public CourseBuilder addName(String name){course.setName(name);return this;}public CourseBuilder addPpt(String ppt){course.setPpt(ppt);return this;}public CourseBuilder addVideo(String video){course.setVideo(video);return this;}public Course build(){return this.course;}
}public class Test {public static void main(String[] args) {CourseBuilder builder = new CourseBuilder().addName("设计模式").addPpt("【ppt】").addVideo("【视频】");System.out.println(builder.build());}
}

在JDK中StringBuilder,它提供append()方法,就是应用了建造者模式。

建造者模式的优缺点:

优点:

1、封装性好,创建和使用分离;

2、扩展性好,建造类之间独立,一定程度上解耦。

缺点:

1、产生多余的Builder对象

2、产品内部发生变化,建造者都要修改,成本比较大。

建造者模式和工厂模式的区别:

1、建造者模式更加注重方法的调用顺序,工厂模式注重于创建对象。

2、创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。

3、关注点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建这个对象,还要知道这个对象由哪些部件组成。

4、建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。

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

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

相关文章

【达梦数据库】查看pesg回滚段信息的视图和SQL

一些达梦回滚段是使用情况的查询SQL&#xff0c;供排查“回滚记录版本太旧&#xff0c;无法获取用户记录” 等类似问题时使用 视图名说明主库备库v$pseg_items显示回滚系统中当前回滚项信息&#xff08;回滚线程的工作信息&#xff09;总行数WORKER_THREADS1查询 no rowsv$pseg…

安装Windows Server 2025 搭建免费云桌面系统

介绍 Windows Server 2025 为 Hyper-V 带来了多项增强功能和新的存储特性&#xff0c;主要用于优化虚拟机的运行体验。这些新特性涵盖 GPU 虚拟化、新的 ReFS 去重功能&#xff0c;以及在非 AD 域的集群上进行虚拟机实时迁移。 云桌面方案的用户最关心的GPU-P的技术也将在Win…

VMware虚拟机文件夹共享失效

问题现象 今天开启虚拟机的时候就看到这个&#xff0c;感觉又要有不好的事情发生了。 果不其然&#xff0c;开机之后弹出这个&#xff0c;我当时还没意识到这个dll文件会对我的正常使用产生什么样的影响。 然后就发现文件根本拷贝不进去虚拟机里面&#xff0c;连虚拟机里面的共…

缓存篇—缓存雪崩、缓存击穿、缓存穿透

缓存异常会面临的三个问题&#xff1a;缓存雪崩、击穿和穿透。 其中&#xff0c;缓存雪崩和缓存击穿主要原因是数据不在缓存中&#xff0c;而导致大量请求访问了数据库&#xff0c;数据库压力骤增&#xff0c;容易引发一系列连锁反应&#xff0c;导致系统奔溃。不过&#xff0…

petalinux_zynq7 驱动DAC以及ADC模块之三:实现C语言API并编译出库被python调用

前文&#xff1a; petalinux_zynq7 C语言驱动DAC以及ADC模块之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

跨界计算与控制,强化显控和UI, 君正MPU再添新旗舰--Ingenic MPU X2600隆重发布

近日&#xff0c;北京君正隆重发布MPU芯片新产品X2600。该产品以商业和工业应用的数个细分领域为重点目标市场&#xff0c;兼顾通用处理器应用需求。无论从CPU结构的设计&#xff0c;还是专门控制器和接口的配备&#xff0c;都体现了北京君正MPU团队“技术路线上追求自主跨界&a…

力扣101 对称二叉树 Java版本

文章目录 题目描述递归解法非递归解法 题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出…

性能全面提升!探索ONLYOFFICE最新8.0版:更快速、更强大,PDF表单编辑轻松搞定!

文章目录 PDF表单功能表单模板 屏幕朗读器功能EXCEL新增功能单变量求解图表向导数字排序 PPT 新增功能新增语言区域设置和优化插件界面 ONLYOFFICE 是由 Ascensio System SIA 推出的一款功能强大的办公套件&#xff0c;其中提供了适用于文本文档、表格以及演示文稿的在线编辑软…

前端|Day2:列表、表格、表单(黑马笔记)

Day2&#xff1a;列表、表格、表单 目录 Day2&#xff1a;列表、表格、表单一、列表1.无序列表2.有序列表3. 定义列表 二、表格1.基本使用2. 表格结构标签(了解)3.合并单元格 三、表单1.input 标签2.input 标签占位文本3.单选框4.上传文件5.多选框6.下拉菜单7.文本域8.label 标…

基于深度学习的红肉新鲜过期判决系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 系统构成与流程 4.2 模型训练与优化 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ...............................................…

C#使用一个泛型方法操作不同数据类型的数组

目录 一、泛型方法及其存在的意义 二 、实例 1.源码 2.生成效果 再发一个泛型方法的示例。 一、泛型方法及其存在的意义 实际应用中&#xff0c;查找或遍历数组中的值时&#xff0c;有时因为数组类型的不同&#xff0c;需要对不同的数组进行操作&#xff0c;那么,可以使用…

蓝桥杯冲C++组还是选Python组从零开始?

蓝桥杯冲C&#xff0b;&#xff0b;组还是选Python组从零开始&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家…

Stable Diffusion 模型分享:Dark Sushi Mix 大颗寿司Mix

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

关于fastjson中JSONPath的使用

关于fastjson中JSONPath的使用 1 简介2 API3 语法4 案例 在项目中, 经常会涉及到对json字符串,进行查询, 添加,删除的处理操作. 传统方法需要一步一步进行处理,并且处理完需要将值进行封装. 而fastjson中提供的JSONPath, 可以更加简单的实现上述功能. 1 简介 JsonPath是一种简…

Mongodb $text详解

在建立文本索引的集合中&#xff0c;使用$text&#xff0c;mongodb能够支持文本检索。本文结合mongodb官方文档详细描述$text的定义&#xff0c;用法&#xff0c;注意事项并实践官网给出的应用举例。 定义 $text在包含文本索引字段的集合中&#xff0c;执行文本检索。 语法 …

苍穹外卖Day02——总结2

前期文章 文章标题地址苍穹外卖Day01——总结1https://blog.csdn.net/qq_43751200/article/details/135466359?spm1001.2014.3001.5501苍穹外卖Day01——解决总结1中存在的问题https://lushimeng.blog.csdn.net/article/details/135473412 总结2 前期文章1. 新增员工模块1.1 …

Linux-Project

1.【minishare】 1.1项目要求 1.1.1编写项目文档 1.项目需求项目背景描述实现该原因及背景需求分析分析项目要求(不涉及技术)概要设计根据需求设计相关技术实现功能软件框图:各个模块之间的功能及其关系模块设计具体每个功能的模块设计流程图:每个模块实现功能的具体步骤及方…

抖店类目怎么选?七大类目详尽分析,总有一个适合你!

我是电商珠珠 在类目的选择上&#xff0c;很多人都会大意。认为类目跟风选一个热销的&#xff0c;后期着重选品就可以了。但做店铺最重要的就是类目&#xff0c;类目作为一个店铺的方向&#xff0c;决定着店铺的流量和后期的订单量。所谓的确定类目&#xff0c;就相当于你写作…

分布式学习Day5

文章目录 初始ES介绍倒排索引ES和MYSQL对比安装ES及其组件1.1.创建网络1.2.加载镜像1.3.运行2.1.部署 分词器 操作索引库文档操作RestAPI介绍 初始ES 介绍 倒排索引 ES和MYSQL对比 安装ES及其组件 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kiban…

【鸿蒙 HarmonyOS 4.0】网络请求

一、介绍 资料来自官网&#xff1a;文档中心 网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1a;通过HTTP发起一个数据请求。WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接。Socket连接&#xff1a;通过Socket进行数据传输。 日常…