创建型设计模式 - 原型设计模式 - JAVA

原型设计模式

    • [一 .简介](#一 .简介)
    • [二. 案例](#二. 案例)
    • [三. 补充知识](#三. 补充知识)

前言

这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。

作者:神的孩子都在歌唱

一 .简介

原型模式提供了一种机制,可以将原始对象复制到新对象,然后根据我们的需要进行修改。原型设计模式使用java克隆来复制对象。

原型模式的克隆分为浅克隆和深克隆。

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是指在进行对象复制时所产生的两种不同结果。

深拷贝:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

浅拷贝:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

Java中的Object类中提供了 clone() 方法来实现浅克隆。 Cloneable 接口是上面的类图中的抽象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。

二. 案例

通过一个例子就很容易理解原型设计模式 。假设我们有一个从数据库加载数据对象 。现在我们需要在程序中多次修改这些数据 ,因此使用通过new 一个新的对象,并再次从数据库加载所有数据并不是一个好主意。更好的方法是将现有对象克隆新对象 中,然后进行数据操作 。原型设计模式其实就是需要你确保正在拷贝的对象 应该提供拷贝功能 。它不应该由任何其他类完成 。然而,是否使用对象属性的浅拷贝深拷贝 取决于 需求及其设计决策

以下是代码案例:

这里我定义了一个篮球类,通过重新实现clone方法来实现深拷贝

java 复制代码
/**
 * @author chenyunzhi
 */
public class Ball implements Cloneable{

	private final List<String> ballList;
	
	public Ball(){
		ballList = new ArrayList<>();
	}
	
	public Ball(List<String> ballList){
		this.ballList=ballList;
	}

	/**
	 * 模拟从数据库中拿数据
	 */
	public void loadData(){
		ballList.add("basketball");
		ballList.add("soccer");
	}
	
	public List<String> getBallList() {
		return ballList;
	}

	@Override
	public Ball clone() throws CloneNotSupportedException {
			return new Ball(new ArrayList<>(this.getBallList()));
	}

	
}

然后我写了一个测试类方便测试,这里我new了一个 ball 对象 ,然后对ball对象 进行拷贝,对拷贝的对象进行了增添删除他们相互之间都不影响

java 复制代码
/**
 * @author chenyunzhi
 */
public class PrototypePatternTest {

	public static void main(String[] args) throws CloneNotSupportedException {

		Ball ball = new Ball();
		ball.loadData();
		Ball ballNew =ball.clone();
		Ball ballNew1 = ball.clone();
		List<String> list = ballNew.getBallList();
		list.add("tennis");
		List<String> list1 = ballNew1.getBallList();
		list1.remove("basketball");
		// 输入修改后的球类列表
		System.out.println("ball List: "+ball.getBallList());
		System.out.println("ballNew List: "+list);
		System.out.println("ballNew1 List: "+list1);
		System.out.println("ball List: "+ball.getBallList());
	}

}

测试结果

结论:如果没有提供对象克隆,我们每次都必须调用数据库来获取球类列表。然后进行那些耗费资源和时间的操作。这就是java中原型设计模式的全部内容。

三. 补充知识

问题: 为什么浅拷贝拷贝的对象 修改了某个String类型的值被拷贝对象的值没有变化?

在Java类库中,所有基本类型的包装类都是不可变类,例如Integer、Float等。

不可变类(Immutable Class) 在初始化后的所有信息不能被修改 。而更改String成员的值相当于在堆中新建一个String引用,旧的String常量引用仍然存在于堆中,只不过还没回收,从而让两个引用不相等。这时你以为String是被克隆,但造成其不相等的原因其实是赋值。

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

相关推荐
青云交几秒前
【金仓数据库征文】-- 金仓数据库:技术实践天花板级深度解析,手把手教你玩转企业级应用
java·性能调优·集群部署·金仓数据库 2025 征文·数据库平替用金仓·金仓数据库·语法兼容
AI视觉网奇3 分钟前
3d关键点 可视化
开发语言·python·pygame
敲代码的 蜡笔小新12 分钟前
【行为型之观察者模式】游戏开发实战——Unity事件驱动架构的核心实现策略
观察者模式·unity·设计模式·c#
向宇it12 分钟前
【unity游戏开发——编辑器扩展】使用EditorGUI的EditorGUILayout绘制工具类在自定义编辑器窗口绘制各种UI控件
开发语言·ui·unity·c#·编辑器·游戏引擎
Paran-ia13 分钟前
【2025版】Spring Boot面试题
java·spring boot·后端
LUCIAZZZ23 分钟前
JVM之虚拟机运行
java·jvm·spring·操作系统·springboot
Python私教27 分钟前
Rust:重新定义系统编程的安全与效率边界
开发语言·安全·rust
hello_ejb332 分钟前
聊聊JetCache的缓存构建
java·前端·缓存
cainiao0806051 小时前
Java 大视界——Java 大数据在智慧交通智能停车诱导系统中的数据融合与实时更新
java·大数据·开发语言
瑞雪兆丰年兮1 小时前
数学实验(Matlab符号运算)
开发语言·算法·matlab·数学实验