Java设计模式-原型模式

embedded/2024/10/16 2:25:07/

概念:

原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过标准构造函数来创建。在原型模式中,新对象的创建是通过克隆现有对象而实现的,因此它是基于原型对象的复制而创建新对象的。
在Java中,原型模式通常通过实现 Cloneable 接口和重写 clone() 方法来实现。Cloneable 接口是一个标记接口,它指示了该类的实例可以被克隆。然后,通过重写 clone() 方法来实现对象的克隆。
换一个方式理解
原型模式就像是制作复印件一样。假设你有一份文件,想要多份一模一样的,但是你又不想重新从头写一遍。这时候,你可以使用原型模式:先制作一份原始文件,然后通过复制这份原始文件,就可以得到多份完全相同的副本。

代码1:

java">/*** 怎么实现克隆。拷贝?* 1、实现一个接口:* 2、重写一个方法*/
public class Video implements Cloneable{//克隆视频private String name;private Date createTime;/*** 重写克隆方法* @return* @throws CloneNotSupportedException*/@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public Video(String name, Date createTime) {this.name = name;this.createTime = createTime;}public Video() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Video{" +"name='" + name + '\'' +", createTime=" + createTime +'}';}
}

我们这有一个视频类。实现了Cloneable接口并重写clone()方法。这个clone()方法调用父类的克隆方法。而这个父类中的clone()是在本地克隆
在这里插入图片描述

测试类
java">import java.util.Date;/*** 客户端。实现克隆*/
public class BiliBiliClient {public static void main(String[] args) throws CloneNotSupportedException {Date date = new Date();//需要一个原型对象实现克隆//原型对象叫做v1Video v1 = new Video("Java从入门到精通", date);System.out.println("v1=====>"+v1);System.out.println("v1.hashCode=====>"+v1.hashCode());//v1可以克隆v2Video v2 = (Video) v1.clone();System.out.println("v2=====>"+v2);System.out.println("v2.hashCode=====>"+v2.hashCode());//修改v2的值v2.setName("张三");System.out.println(v2);}
}

创建一个BliBlili客户端类实现克隆,首先,我们先把原型对象创建出来,v1的hashCode输出。我们在想创建一个v2对象的时候,传统的方式是不是还需要new Video对象,但是现在我们可以直接使用v1.clone()方法进行创建,返回的是一个Object类。强制转换成Video对象。在进行把克隆的内容V2进行输出。此时两个对象内容一样,但是hashCode不一样

测试结果:

在这里插入图片描述

问题:

在这里插入图片描述
V2对象是V1对象拷贝过来的。但是他们还是指向同一个地址。

验证:

修改客户端的代码:

java">import java.util.Date;/*** 客户端。实现克隆*/
public class BiliBiliClient {public static void main(String[] args) throws CloneNotSupportedException {Date date = new Date();//需要一个原型对象实现克隆//原型对象叫做v1Video v1 = new Video("Java从入门到精通", date);Video v2 = (Video) v1.clone();System.out.println("v1原始的值:=====>"+v1);System.out.println("v2原始的值:=====>"+v2);//修改后的值,把date数值改变一下System.out.println("==================================");date.setTime(12345678);System.out.println("v1修改后的:=====>"+v1);System.out.println("v2修改后的:=====>"+v2);//
//
//        System.out.println("v1.hashCode=====>"+v1.hashCode());
//        //v1可以克隆v2
//
//        System.out.println("v2=====>"+v2);
//        System.out.println("v2.hashCode=====>"+v2.hashCode());
//        //修改v2的值
//        v2.setName("张三");
//        System.out.println(v2);}
}

此时我们修改V1的值。上图所示,我们v1指向的是data。但是v2是v1克隆出来的。地址值是没有变化的。所以这是浅克隆。

测试结果:

在这里插入图片描述
我们理想的情况是:深度克隆
在这里插入图片描述
地址也会完全变化的。最简单的一种就是改造克隆的方法、修改原型类中的克隆方法实现深度克隆:

代码2:

java">package com.MrSun.PrototypeTest.demo02;import java.util.Date;public class Video implements Cloneable{private String name;private Date createTime;/*** 重写克隆方法* @return* @throws CloneNotSupportedException*/@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();//深度克隆Video v=(Video) obj;//将这个对象的属性也进行克隆v.createTime= (Date) this.createTime.clone();return obj;}public Video(String name, Date createTime) {this.name = name;this.createTime = createTime;}public Video() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Video{" +"name='" + name + '\'' +", createTime=" + createTime +'}';}
}

主要就修改了cole方法

    @Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();//深度克隆Video v=(Video) obj;//将这个对象的属性也进行克隆v.createTime= (Date) this.createTime.clone();return obj;}

我们对里面的属性也进行克隆。这样就可以实现深度克隆、

验证:

在这里插入图片描述
加油!!!!!!!!!!


http://www.ppmy.cn/embedded/17646.html

相关文章

隧道智能巡检机器人:科技助力隧道维护与管理

在现代社会,隧道已经成为城市、交通网络和基础设施的重要组成部分。尽管如此,隧道的安全运营和维护仍然存在着各种挑战。传统的隧道巡查方式主要依赖于人工巡检,但这种方式存在诸多问题,如工作负荷大、检测标准不统一、效率低下、…

详解23种设计模式——单例模式

单例模式 | CoderMast编程桅杆单例模式 单例模式是最常用的设计模式之一,他可以保证在整个应用中,某个类只存在一个实例化对象,即全局使用到该类的只有一个对象,这种模式在需要限制某些类的实例数量时非常有用,通常全局…

【R语言简介】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

JVM学习笔记(五)内存模型

目录 1、原子性 1.1 问题分析 1.2 解决方法 2、可见性 2.1 退不出的循环 2.2 解决办法 3、有序性 3.1 诡异的结果 3.2 解决办法 3.3 有序性理解 3.4 happens-before 4、CAS与原子类 4.1 CAS 4.2 乐观锁与悲观锁 4.3 原子操作类 5、synchronized 优化 5.1 轻量…

JVM之初识垃圾收集器

JDK 8:Parallel Scavenge(新生代) Parallel Old(老年代)JDK8以后:G1收集器 什么是串行回收和并行回收? Serial收集器:串行收集器 新生代使用标记复制算法,老年代使用标记…

GITEE本地项目上传到远程

由于需要,我这边将本地的仓库上传至GITEE。之前在网上搜索了相关的文档,但是步骤很繁琐,我这边介绍一个非常简单的。 一、在GITEE新建仓库 跟着指引一步步新建。 二、打开本地仓库,删除.git文件 默认情况下不会有这个.git文件&a…

iOS - 多线程-GCD-队列组

文章目录 iOS - 多线程-GCD-队列组1. 队列组1.1 基本使用步骤 iOS - 多线程-GCD-队列组 开发过程中,有时候想实现这样的效果 多个任务并发执行所有任务执行完成后,进行下一步处理(比如回到主线程刷新UI) 1. 队列组 可以使用GC…

Win 进入桌面黑屏,只有鼠标

大家好,我叫秋意零。 今天,遇到一个同事电脑进入桌面黑屏,只有鼠标。经过询问沟通,说是 Windows 突然进行了自动更新,更新之后桌面就黑了屏。经过查询是一个桌面进程没启动才会导致桌面黑屏。首先分两种情况&#xff0…