设计模式——原型模式

2023-11-19

       原型模式顾名思义,就是指以某个实例为原型,copy出一个新的实例,该实例属性与原型相同或者是类似。

        很多时候,我们需要创建大量的相同或者相似的对象,如果一个个用new 构造函数的形式去创建的话比较繁琐,就像孙悟空要想变出成千上万个猴子猴孙总不能一个个去生吧,拔一根猴毛一吹就copy出了成千上万个猴子猴孙,我们原型模式原理也是如此,那就是clone克隆。

        我们都知道JAVA中有个祖宗级别的类Object,每个类都默认继承它,它提供了一个本地方法clone(),代码如下:

protected native Object clone() throws CloneNotSupportedException;

可以看到它抛出了一个CloneNotSupportedException异常,不支持克隆,其实这个本地方法中有做一件事情,那就是判断原型类有没有实现CloneAble接口,如果没有,那就直接抛出该异常,我随便建了个实例调用clone方法,确实该抛异常了。

 这就是原型模式一个典型的特点,规定了具体原型对象必须实现的接口。

原型模式包含以下主要角色。
(1)抽象原型类:规定了具体原型对象必须实现的接口。
(2)具体原型类:实现抽象原型类的clone()方法,它是可被复制的对象。
(3)访问类:使用具体原型类中的clone()方法来复制新的对象。

在上面的例子中Object就是抽象原型类,他规定了原型类必须实现CloneAble接口。

原型模式的结构图如下:

         原型模式的克隆又分为浅克隆跟深克隆

        Java中Object类中的clone()的实现是浅克隆,浅克隆指复制值类型,引用类型的地址不复制,也就是说克隆出来的对象中的引用类型的成员变量的地址跟原型中的地址是同一个,经常会一不注意就掉这坑里了,这也是原型模式的一个缺点吧。

        深克隆就正好填上了那个坑,一般采用序列化+流的方式,在clone()方法中将原型对象序列化并写入流中,再从流中将字节流取出来反序列化成原型对象,此时,对象地址已经改变。代码如下:

public SubAccountInfo clone(){
        SubAccountInfo subAccountInfo = null;
        try {
            //将对象序列化到流里
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);
            //将流反序列化成对象
            ByteArrayInputStream is = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(is);
            subAccountInfo = (SubAccountInfo) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return subAccountInfo;
    }

这里要注意原型类需要实现Serializable接口,否则无法序列化,抛出异常如下:

java.io.NotSerializableException: GamePlusCom.GamePlus.game.entity.subAccount.SubAccountInfo
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at GamePlusCom.GamePlus.game.entity.subAccount.SubAccountInfo.clone(SubAccountInfo.java:78)
	at GamePlusCom.GamePlus.game.constant.GlobalConstant.main(GlobalConstant.java:36)

原型模式就讲到这,原型模式跟单例模式都属于创建型模式,创建型模式还有工厂方法模式、抽象工厂模式、建造者模式,有时间我会一一分享。

分享是种乐趣~~~修BUG也是

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式——原型模式 的相关文章

  • 上传进度条 Java Servlet?

    我想使用 servlet 显示上传进度条 我尝试过Ajax iFrame 技术 页面没有重新加载 文件也被上传 但是 进度条没有出现 有没有可用于 javaservlts 的 jQuery 进度插件 Thanks 我强烈推荐jQuery 上
  • 枚举的子类化

    有没有一种简单的方法来子类化Javaenum 我问这个问题是因为我有大约 10 个实现相同接口的对象 但它们对某些方法也有相同的实现 因此我想通过将所有相同的实现放置在扩展的中间对象中来重用代码Enum它也是我需要的所有其他类的超类 或许事
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • 连接外部 Accumulo 实例和 java

    我正在尝试使用 Accumulo 连接到虚拟机 问题是 我无法将其连接到 Java 中 我可以看到 Apache 抛出的网页 但我无法让它与代码一起工作 我认为这是缺乏知识的问题而不是真正的问题 但我找不到这方面的文档 所有示例都使用 lo
  • 为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值?

    我不明白 a 的值为0 为什么 a 不是10 那段代码的运行过程是怎样的 是否需要从Java内存模型来分析 这是我的测试代码 package com study concurrent demo import lombok extern sl
  • Java中Gson、JsonElement、String比较

    好吧 我想知道这可能非常简单和愚蠢 但在与这种情况作斗争一段时间后 我不知道发生了什么 我正在使用 Gson 来处理一些 JSON 元素 在我的代码中的某个位置 我将 JsonObject 的 JsonElements 之一作为字符串获取
  • getCurrentSession 在网络中休眠

    我正在使用 hibernate 和 jsp servlet 编写一个基于 Web 的应用程序 我读过有关sessionFactory getCurrentSession and sessionFactory openSession方法 我知
  • JAXB - 忽略元素

    有什么方法可以忽略 Jaxb 解析中的元素吗 我有一个很大的 XML 文件 如果我可以忽略其中一个大而复杂的元素 那么它的解析速度可能会快很多 如果它根本无法验证元素内容并解析文档的其余部分 即使该元素不正确 那就更好了 例如 这应该只生成
  • 为什么解析这个 JSON 会抛出错误?

    我正在尝试解析这个 JSONObject query yahoo count 1 results rate Name USD INR id USDINR Time 12 19pm Date 10 31 2015 Bid 65 405 Ask
  • 如何使用双重调度来分析图形基元的交集?

    我正在分析图形基元 矩形 直线 圆形等 的交互并计算重叠 相对方向 合并等 这被引用为双重调度的一个主要示例 例如维基百科 http en wikipedia org wiki Double dispatch 自适应碰撞算法通常要求 不同的
  • 无需递归即可对可观察结果进行分页 - RxJava

    我有一个非常标准的 API 分页问题 您可以通过一些简单的递归来处理 这是一个捏造的例子 public Observable
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • 使用 Proguard 通过 Dropbox.com 库混淆 Android 应用程序

    我刚刚创建了一个需要 Dropbox com API 库的 Android 应用程序 我现在尝试在 发布 模式下构建应用程序 并希望在代码上运行混淆器以对其进行混淆 但是 每当我尝试运行 Proguard 时 都会收到以下错误 Progua
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • 按降序排序映射java8 [重复]

    这个问题在这里已经有答案了 private static
  • titledBorder 标题中的图标

    您好 是否可以在 titledBorder 的标题中放置一个图标 例如以下代码 import java awt GridLayout import javax swing JFrame import javax swing JLabel i
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐

  • 数据集下载OTB,VOT,UAV,鸢尾花

    OTB数据集下载百度网盘链接 链接 https pan baidu com s 1snsJF 7Sw EbKtzdvLO1nw 提取码 ls23 VOT数据集下载百度网盘链接 链接 https pan baidu com s 1UiTG1z
  • AI顶级会议列表 & ACL相关

    The First Class tier 1的conferences 其实基本上就是AI里面大家比较公认的top conference 下面同分的按字母序排列 IJCAI 1 AI最好的综合性会议 1969年开始 每两年开一次 奇数年开 因
  • 基于互补搜索技术和新颖架构设计,结合MobileNetV3主干网络,打造不同的目标检测器

    基于互补搜索技术和新颖架构设计 结合MobileNetV3主干网络 打造不同的目标检测器 目标检测是计算机视觉中的一个重要任务 随着深度学习技术的发展和神经网络的不断优化 YOLOv5已成为目前最流行的目标检测框架之一 然而 为了进一步提高
  • opengl shader 使用札记

    一 shader的使用步骤 创建shader 1 创建一个shader对象 GLuint glCreateShader GLenum shaderType 2 将shader源代码传入前面创建的shader对象 void glShaderS
  • 老嫂子的保姆级科普 选择视频剪辑软件就从阅读本文开始

    选错一款视频剪辑软件 是种什么样的体验 就好像新婚当晚 发现老婆是人妖一样 浪费了感情 又错付了青春 新手在学习视频剪辑的初期 需要花费大量精力去熟悉剪辑软件的基础功能 而软件挑选本身没有对错可言 适合自己的才是最好的 因此 本文仅从事实与
  • 初识Java(一)

    Java开发语言 前言 一 Java是什么 二 应用领域 特点及核心机制 1 应用领域 2 特性及特点 特性 特点 3 两种核心机制 三 JDK JRE JVM的关系 四 Java环境变量配置 五 编写我的第一个程序 总结 前言 计算机语言
  • C# 实现rabbitmq 延迟队列功能(不堵塞)

    最近在研究rabbitmq 项目中有这样一个场景 在用户要支付订单的时候 如果超过30分钟未支付 会把订单关掉 当然我们可以做一个定时任务 每个一段时间来扫描未支付的订单 如果该订单超过支付时间就关闭 但是在数据量小的时候并没有什么大的问题
  • 计算机基础msoffice等宽两缆,一级计算机基础及《MSOffice应用》模拟题

    一级计算机基础及 MSOffice应用 模拟题 三 字处理题 共25分 26 在考生文件夹下打开文档WORD DOCX 按照要求完成下列操作并以该文件名 WORD oocx 保存文档 文档开始 IBM电子商务专利的特点 通过对IBM e c
  • Typora主题下载

    1 0前言 Typora有很多主题可以使用 默认的主题很少 想要自己的主题更加个性化 可以去添加更多的主题来优化自己的使用体验 2 0下载主题 2 1 找到Typora主题的网站 1 打开一个typora文件此点击 2 进入偏好设置 3依次
  • 【目标检测】32、让你一文看懂且看全 NMS 及其变体

    文章目录 一 NMS 1 1 背景 1 2 方法 1 3 代码 1 4 不足 二 Soft NMS 2 1 背景 2 2 方法 2 3 效果 2 4 代码 2 5 不足 三 Softer NMS 3 1 背景 3 2 方法 四 IoU Ne
  • MySQL开启bin_log后导致创建函数、存储过程失败。Error:Result_ 1418 - This function has none of DETERMINISTIC

    搭建分布式服务 使用了主从数据库 需要使用MySQL的binlog去同步数据 但是开启binlog后导致新增函数 存储过程等报错 具体报错信息如下 Result 1418 This function has none of DETERMIN
  • kitti depth complement

    代码 运行环境 windows10 open3d版本 0 12 0 import cv2 import numpy as np import os import math import open3d as o3d basic path D
  • 【好工具】网页剪藏+免费云端笔记+一键变博客

    欢迎大家来到 好工具 专栏 这个专栏面向所有希望获得高效生产力工具的朋友 在这个专栏里 我们会和大家聊聊那些狂拽酷霸炫的生产力工具 相信大家一定我一样 茫然于庞大的工具海洋 却仍找不到称心的它来使用 这也是 好工具 专栏存在的意义 发掘 折
  • 贝叶斯优化及其python实现

    贝叶斯优化是机器学习中一种常用的优化技术 其目的是在有限步数内寻找函数的最大值或最小值 它可以被视为在探索不同参数配置与观察这些配置结果之间寻求平衡点的过程 基本思想是将我们在过去的观察和体验 传递到下一个尝试中 从而在等待数据的反馈时 逐
  • 微信小程序开发实战第五讲之授权登录

    上一节 我们实现了简单的通过用户名和密码调用接口进行登录的实战 但是在小程序中 有个特殊的情况 就是很少有厂商去开发一个注册功能或者是通过用户名 密码来登录的逻辑 为什么 因为APP 小程序为了用户体验 是尽量多的避免用户多次输入交互 所以
  • 物联网LoRa系列-17:LoRa终端Sx1262芯片内部的射频信号放大器

    至此 我们已经拆解了天线是如何发送和接收空中的无线电磁波信号 拆解了无线终端如何对射频前端的高频电信号进行进一步处理的 还拆解了无线终端的发送和接收如何分时复用天线的半双工模式 本篇将进一步拆解无线终端是如何对射频电信号进行进一步的处理 包
  • 【优化器】(一) SGD原理 & pytorch代码解析

    1 简介 很多情况下 我们调用优化器的时候都不清楚里面的原理和构造 主要基于自己数据集和模型的特点 然后再根据别人的经验来选择或者尝试优化器 下面分别对SGD的原理 pytorch代码进行介绍和解析 2 梯度下降 梯度下降方法可以分为3种
  • constexpr 用法

    1 简介 constexpr函数指的是在编译的时候就能得到其返回值的函数 也就是说编译器将constexpr函数直接转换成其返回值 因此 constexpr函数都是被隐式地定义为内联函数 使用constexpr关键字来修饰constexpr
  • C++设计模式(二)观察者模式

    1 观察者模式知识点 1 定义 定义对象间的一种一对多的依赖关系 当一个对象的状态发生改变的时候 所有依赖它的对象都得到通知并自动更新 2 动机 将一个系统分割成一系列相互协作的类有一个常见的副作用 需要维护相关对象间的一致性 我们不希望为
  • 设计模式——原型模式

    原型模式顾名思义 就是指以某个实例为原型 copy出一个新的实例 该实例属性与原型相同或者是类似 很多时候 我们需要创建大量的相同或者相似的对象 如果一个个用new 构造函数的形式去创建的话比较繁琐 就像孙悟空要想变出成千上万个猴子猴孙总不