Java设计模式-原型模式

server/2024/12/22 9:00:15/

概念:

原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过标准构造函数来创建。在原型模式中,新对象的创建是通过克隆现有对象而实现的,因此它是基于原型对象的复制而创建新对象的。
在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/server/10317.html

相关文章

RK平台 启动硬件加速

1.xml中添加需要加速的包名 /device/rockchip/rk356x/package_performance.xml <?xml version1.0 encodingutf-8 standaloneyes ?> <performance-package> <app package"com.antutu.ABenchMark" mode"1"/> <app package"com…

自建SQL server 服务无法启动,提示评估期已过

问题背景 在服务器内安装的SQL server无法启动&#xff0c;报错提示如下截图&#xff0c;提示错误代码17051&#xff1a; 结合系统日志查看应用程序日志详情提示评估期已过&#xff0c;报错如下 问题原因 出现此报错原因是SQL server 安装时&#xff0c;使用的评估版本&#xf…

1、初识Linux系统 shell 脚本

shell脚本组成介绍 1、shell脚本命名规则 必须以.sh文件结尾&#xff0c;类似.txt文件&#xff1b;例如创建一个test.sh文件 2、linux系统中shell脚本开头&#xff0c;必须以如下代码开头 test.sh内容如下&#xff1a; #!/bin/bash# 这是一个注释echo "Hello, World!&…

【ARM 裸机】C 语言 led 驱动

前面刚学习了汇编 led 驱动的编写和验证&#xff0c;现在开始就要进入 C 语言 led 驱动编写与验证了 ! 1、C 语言运行环境构建 1.1、设置处理器模式 使 6ULL 处于 SVC 模式下&#xff0c;之前已经提到了处理器的九种模式&#xff0c;参考&#xff1a;【ARM 裸机】汇编 led 驱…

ui_admin_vue3启动

1、要求node版本16.20.2&#xff0c;小于这个版本npm run dev会报错UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token ‘??‘ 逻辑空赋值(??)是ES2021的语法&#xff0c;node v15.0.0以上才支持逻辑空赋值(??)的语法。之前为了兼容旧代码使用的node版本…

手拿滑块撕瑞数,我叫超弟你记住!腾讯滑块2024.4.23最新版,高复用,看到就是赚到,珍惜资源首次公开!!!

众所周知&#xff0c;腾讯阿里系安全属于国内天花板&#xff0c;让很多同行望眼欲穿&#xff0c;却束手无策&#xff0c;我们小团队因业务需要&#xff0c;一直都有现成的解决方案&#xff0c;有需求的朋友可以私信&#xff0c;后续准备办一个商学院&#xff0c;完全分享行内超…

【数据结构(邓俊辉)学习笔记】向量01——接口与实现

文章目录 0.意图1、概述2 从数组到向量3 向量ADT接口4 Vector 模板类5 构造与析构5.1默认构造方法5.2基于复制的构造方法5.3 析构方法 0.意图 一方面是将工作学习中零星的知识点串起来&#xff0c;另一方面向量是其他数据类型的基础&#xff0c;比如栈队列等&#xff0c;所以基…

Docker NetWork (网络)

Docker 为什么需要网络管理 容器的网络默认与宿主机及其他容器都是相互隔离的&#xff0c;但同时我们也要考虑下面的一些问题&#xff0c; 比如 多个容器之间是如何通信的容器和宿主机是如何通信的容器和外界主机是如何通信的容器中要运行一些网络应用(如 nginx、web 应用、数…