java设计模式之原型模式

news2024/11/19 10:34:01

一:原型模式

1.什么是原型模式?
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
基本介绍
1.原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
2.原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节
3.工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone()
4.形象的理解:孙大圣拔出猴毛, 变出其它孙大圣

2.原型模式适合应用场景
1.如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
2.这一点考量通常出现在代码需要处理第三方代码通过接口传递过来的对象时。 即使不考虑代码耦合的情况, 你的代码也不能依赖这些对象所属的具体类, 因为你不知道它们的具体信息。
3.原型模式为客户端代码提供一个通用接口, 客户端代码可通过这一接口与所有实现了克隆的对象进行交互, 它也使得客户端代码与其所克隆的对象具体类独立开来。
4.Spring中原型bean的创建,就是原型模式的应用

3. 原型模式优缺点
优点:
1.你可以克隆对象, 而无需与它们所属的具体类相耦合。
2.你可以克隆预生成原型, 避免反复运行初始化代码。
3.你可以更方便地生成复杂对象。
4.你可以用继承以外的方式来处理复杂对象的不同配置。
缺点:
1.克隆包含循环引用的复杂对象可能会非常麻烦。

4.原型模式实现
原型模式的克隆分为浅克隆和深克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原
有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

二:原型模式代码实现

原型模式包含如下角色:
抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。
浅克隆

//具体原型类
public class Sheep implements Cloneable {
	private String name;
	private int age;
	private String color;
	private String address = "蒙古羊";
	public Sheep friend; //是对象, 克隆是会如何处理
	public Sheep(String name, int age, String color) {
		super();
		this.name = name;
		this.age = age;
		this.color = color;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	
	
	
	@Override
	public String toString() {
		return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";
	}
	//克隆该实例
	//重写clone方法,或者用默认的clone方法也行,只不过调用时候需要抛异常
	@Override
	protected Object clone()  {
		Sheep sheep = null;
		try {
			sheep = (Sheep)super.clone();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return sheep;
	}
}


//--访问类
	//可以看出都是克隆的原型,调用原型类的clone来复制对象
	public static void main(String[] args)  {
		System.out.println("原型模式完成对象的创建");
	
		Sheep sheep = new Sheep("tom", 1, "白色");

		sheep.friend = new Sheep("jack", 2, "黑色");

		Sheep sheep2 = (Sheep)sheep.clone(); //克隆
		Sheep sheep3 = (Sheep)sheep.clone(); //克隆
		Sheep sheep4 = (Sheep)sheep.clone(); //克隆
		Sheep sheep5 = (Sheep)sheep.clone(); //克隆
		
		System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
		System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
		System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());
		System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());
	}

在这里插入图片描述

深克隆(原型引用类型,并且原型和引用类型都需要实现序列化,和实现克隆接口)

//原型
public class DeepProtoType implements Serializable, Cloneable{
	
	public String name; //String 属性
	public DeepCloneableTarget deepCloneableTarget;// 引用类型
	public DeepProtoType() {
		super();
	}
	
	
	//深拷贝 - 方式 1 使用clone 方法
	@Override
	protected Object clone() throws CloneNotSupportedException {
		
		Object deep = null;
		//这里完成对基本数据类型(属性)和String的克隆
		deep = super.clone(); 
		
		//克隆引用类型,对引用类型的属性,进行单独处理
		DeepProtoType deepProtoType = (DeepProtoType)deep;
		deepProtoType.deepCloneableTarget  = (DeepCloneableTarget)deepCloneableTarget.clone();
		
		return deepProtoType;
	}
	
	//深拷贝 - 方式2 通过对象的序列化实现 (推荐)
	public Object deepClone() {
		
		//创建流对象
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;
		
		try {
			
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this); //当前这个对象以对象流的方式输出
			
			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			DeepProtoType copyObj = (DeepProtoType)ois.readObject();
			
			return copyObj;
			
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			//关闭流
			try {
				bos.close();
				oos.close();
				bis.close();
				ois.close();
			} catch (Exception e2) {
				System.out.println(e2.getMessage());
			}
		}
	}
	

//引用类型
public class DeepCloneableTarget implements Serializable, Cloneable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String cloneName;

	private String cloneClass;

	//构造器
	public DeepCloneableTarget(String cloneName, String cloneClass) {
		this.cloneName = cloneName;
		this.cloneClass = cloneClass;
	}

	//因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
	//访问类(深克隆的内存对象是不一致的)
	public static void main(String[] args) throws Exception {
		DeepProtoType p = new DeepProtoType();
		p.name = "宋江";
		p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");

		
		//方式1 完成深拷贝
		
//		DeepProtoType p2 = (DeepProtoType) p.clone();
//		
//		System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
//		System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
	
		//方式2 完成深拷贝
		DeepProtoType p2 = (DeepProtoType) p.deepClone();
		
		System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
		System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
	
	}

在这里插入图片描述

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

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

相关文章

STM32CubeMX学习笔记(47)——USB接口使用(MSC基于内部Flash模拟U盘)

一、USB简介 USB(Universal Serial BUS)通用串行总线,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、…

数据库知识之图的创建以及各种遍历、生成树的形成

利用邻接矩阵创建图并打印输出利用递归完成dfs算法遍历利用非递归完成bfs算法遍历利用prim算法得出最小生成树利用kruskal算法得出最小生成树 #include <iostream> #include <cstdlib>//包含一些特定函数 #include <string> //邻接矩阵结构存储图 #defin…

量子计算(六):量子计算软件介绍

文章目录 量子计算软件介绍 一、量子语言 二、量子软件开发包 三、量子云平台 量子计算软件介绍 一、量子语言 由于当前量子计算机的通用体系架构未得到统一&#xff0c;在硬件层面上的技术路线也未最终确定&#xff0c;所以目前还无法确定哪种量子机器指令集相对更科学、…

2010年408大题总结

2010年408大题第41题第42题第43题第44题第45题第46题第47题第41题 这个考的是散列表&#xff08;巧了&#xff0c;我没复习&#xff0c;这就去看&#xff09; 第一个要记住的是装填因子&#xff0c;关键字个数/装填因子 数组长度 第二个是线性探测再散列&#xff0c;表示如果当…

Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)

觉得有帮助请点赞关注收藏~~~ 一、反编译 编译是把代码编译为程序&#xff0c;反编译是把程序破解为代码。 下面介绍反编译的完整过程 首先准备反编译的三个工具&#xff0c;分别是apktool&#xff0c;dex2jar&#xff0c;jd-gui 注意下载它们的最新版本 apktool 对APK文件解…

ASEMI整流桥UD6KB100,UD6KB100尺寸,UD6KB100特征

编辑-Z ASEMI整流桥UD6KB100参数&#xff1a; 型号&#xff1a;UD6KB100 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;1000V RMS反向电压VR(RMS)&#xff1a;700 平均整流输出电流&#xff08;IO&#xff09;&#xff1a;6A 峰值正向浪涌电流&#xff…

imx6ull内置温度传感器实践1:输出一个采样

前言 先写代码&#xff0c;然后再一个问题&#xff0c;一个问题分析。不是应该先分析问题&#xff0c;再写代码吗&#xff1f;因为笨呗。分析不明白。只有看到现象&#xff0c;才能明白手册上说的是啥意思。 实例1 主要完成以下几个事情 1 创建一个misc驱动 2 在驱动中将寄存…

【HDU No. 1232】 畅通工程

【HDU No. 1232】 畅通工程 杭电OJ 题目地址 【题意】 现有城镇道路统计表&#xff0c;表中列出了每条直接相连的城镇道路。“畅通工程”的目标是使全省任意两个城镇间都可以通过道路连接&#xff08;间接通过路连接也可以&#xff09;。问最少还需要建设多少条道路&#xff…

JUC并发编程第一篇,复习线程基础知识

JUC并发编程第一篇&#xff0c;复习线程基础知识一、为什么多线程极其重要&#xff1f;二、从start一个线程开始认识多线程三、进程、线程和管程四、用户线程和守护线程一、为什么多线程极其重要&#xff1f; 硬件方面&#xff1a;摩尔定律失效 摩尔定律 价格不变时&#xff0…

Java毕业设计基于springboot 美妆化妆品销售购物网站多商家 前后端分离node

美妆化妆品是当前很多女性的必备用品&#xff0c;所以为了能够让更多的女士用上物美价廉的化妆品我们开发了本系统。基于springboot 美妆化妆品销售购物网站本系统以java为核心开发技术&#xff0c;结合springboot VUE框架实现了一个美妆化妆品销售管理系统。美妆化妆品销售管理…

InheritableThreadLocal

补充:关于ThreadLocal,请看这篇文章关于ThreadLocal内存泄漏的问题_小星向上的博客-CSDN博客 引言:最近在查看shiro登录成功后,获取当前登录人的信息时发现了里面使用了InheritableThreadLocal,,但是我好奇,如果我在里面新建了一个线程,那怎么获取登录人的信息呢,结果发现shir…

(经典dp) 骨牌问题 2*n 3*n n*m

文章目录前言题目2*n3*nn*mn < 5 && m < 1e9n*m < 100END前言 用1*2的骨牌铺满一个平面&#xff0c;是非常经典的一系列dp题目 (各大平台几乎都有这类题) 并且随着平面的要求不同&#xff0c;难度也是层层递增 对于n*m若数据量不同&#xff0c;则对应处理的…

2022IDEA的下载、安装、配置与使用

文章目录1.IntelliJ IDEA 介绍1.2 JetBrains 公司介绍1.2 IntelliJ IDEA 介绍1.3 IDEA 的主要功能介绍1.3.1 语言支持上1.3.2 其他支持1.4 IDEA 的主要优势&#xff1a;(相较于 Eclipse 而言)1.5 IDEA 的下载地址1.6 官网提供的详细使用文档2.windows 下安装过程2.1 安装前的准…

CANdelaStudio中的状态跳转图无法查看

诊断协议那些事儿 诊断协议那些事儿专栏系列文章&#xff0c;本文将介绍如何解决CANdelaStudio中的状态跳转图无法查看的问题。 参考文章&#xff1a; CDD文件——CANdelaStudio 10服务-DiagnosticSessionControl States To display a graphical representation of the stat…

安装kafka和相关配置解析

1选择操作系统 kafka是一个java应用程序&#xff0c;可以运行在很多系统上Windows, MacOS, Linux, 等 一般都是Linux 2安装java环境 3安装zk zk存储的是metadata 架构图如下 Kafka已经用稳定的zk的3.4.6版本进行了广泛的测试&#xff0c;它可以从apache.org的http://bit.ly/2sD…

摩尔斯电码笔记

文章目录1. 前言2. 什么是摩尔斯电码&#xff1f;3. 摩尔斯电码是如何发明的&#xff1f;4. 摩尔斯电码还在使用吗&#xff1f;5. 如何快速记住6. 体验7. 形式表达8. 相关电影1. 前言 最近突然想起之前学习过的莫斯密码已经忘记了&#xff0c;发现如果不实践的话&#xff0c;就…

OOM和JVM最详细介绍

什么是OOM&#xff1f; OOM&#xff0c;全称“Out Of Memory”&#xff0c;翻译成中文就是“内存用完了”&#xff0c;来源于java.lang.OutOfMemoryError。看下关于的官方说明&#xff1a; Thrown when the Java Virtual Machine cannot allocate an object because it is out…

windows服务器证书算法升级

由于前段时间&#xff0c;服务器检查出证书算法较弱&#xff0c;服务器算法采用的SHA1&#xff0c;这个算法在当前已经较落后了。 第一步在命令端输入certsrv.msc&#xff08;如果打不开&#xff0c;请看我的另一篇文章&#xff0c;先安装服务器证书&#xff09; 第二步打开证…

[LeetCode周赛复盘] 第 91 场双周赛补20221015

[LeetCode周赛复盘] 第 91 场双周赛补20221015 一、本周周赛总结二、 [Easy] 2465. 不同的平均值数目1. 题目描述2. 思路分析3. 代码实现三、[Medium] 2466. 统计构造好字符串的方案数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 2467. 树上最大得分和路径1. 题目描述2. 思…

2.2、物理层下面的传输媒体

2.2、物理层下面的传输媒体 注意&#xff1a; 传输媒体不属于网络体系结构的任何一层。若非要将它添加到体系结构中&#xff0c;那只能放在物理层之下 传输媒体大致分为 2 类 2.2.1、导引型传输媒体 导引型传输媒体 电磁波被导引沿着固体媒体传播常见的导引型传输媒体有同…