设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)

news2024/10/5 5:06:27

文章目录

  • 设计模式概述
  • 1、原型模式
  • 2、原型模式的使用场景
  • 3、优点
  • 4、缺点
  • 5、主要角色
  • 6、代码示例
  • 7、总结
  • 题外话关于使用序列化实现深拷贝

设计模式概述

创建型模式:工厂方法、抽象方法、建造者、原型、单例。
结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。
行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。
常用设计模式:
单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。

1、原型模式

  • 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。
  • 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

2、原型模式的使用场景

  • 需要一个类的大量对象的时候,使用原型模式是最佳选择,因为原型模式是在内存中对这个对象进行拷贝,要比直接new这个对象性能要好很多,在这种情况下,需要的对象越多,原型模式体现出的优点越明显。
  • 如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算,那么可以使用原型模式。
  • 当需要一个对象的大量公共信息,少量字段进行个性化设置的时候,也可以使用原型模式拷贝出现有对象的副本进行加工处理。

3、优点

  • 原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间,由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。

4、缺点

  • 原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候

5、主要角色

(1)客户(Client)角色:客户类提出创建对象的请求。
(2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
(3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。

6、代码示例

1)UML图
在这里插入图片描述
2)源代码
(1)抽象原型角色

public interface Prototype{
    /**
     * 克隆自身的方法
     * @return 一个从自身克隆出来的对象
     */
    public Object clone();
}

(2)具体原型角色


public class ConcretePrototype1 implements Prototype {
    public Prototype clone(){
        //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
        Prototype prototype = new ConcretePrototype1();
        return prototype;
    }
}

public class ConcretePrototype2 implements Prototype {
    public Prototype clone(){
        //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
        Prototype prototype = new ConcretePrototype2();
        return prototype;
    }
}

(3)客户端角色

public class Client {
    public static void main(String[]args){
        try{
            Prototype p1 = new ConcretePrototype1();
            //获取原型来创建对象
            Prototype p2 = p1.clone();
            
            //有人动态的切换了实现
            Prototype p3 = new ConcretePrototype2();
            Prototype p4 = p3.clone();
            
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
}

7、总结

  • 这种情况就是浅拷贝,java只拷贝你指定的对象,至于你指定的对象里面的别的对象,它不拷贝,还是把引用给你,共享变量,这是一种非常不安全的方式,需要特别注意。
  • 内部的数组和引用对象不会拷贝,其他的原始基本类型和String类型会被拷贝。
  • 如果需要可以使用深拷贝,结合具体对象的情况进行处理(可以自己实现深拷贝逻辑;或者利用序列化和反序列化实现深拷贝,前提是所有需要复制的对象都需要实现java.io.Serializable接口。

题外话关于使用序列化实现深拷贝

利用序列化实现深度克隆:

  • 把对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。
  • 在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。
public  Object deepClone() throws IOException, ClassNotFoundException{
        //将对象写到流里
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //从流里读回来
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
  • 这样做的前提就是对象以及对象内部所有引用到的对象都是可序列化的,否则,就需要仔细考察那些不可序列化的对象可否设成transient,从而将之排除在复制过程之外。

  • 浅度克隆显然比深度克隆更容易实现,因为Java语言的所有类都会继承一个clone()方法,而这个clone()方法所做的正式浅度克隆。

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

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

相关文章

构建高效新闻推荐系统:Spring Boot的力量

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…

MacBook远程连接服务器,显示tensorboard的loss值

尼卡形态 GEAR-5 参考链接 当使用服务器进行模型训练时,想要使用MacBook查看一些可视化结果,如果远程服务器和本机在一个局域网内,可以通过以下命令解决: 登录服务器: 先用ssh工具重定向:ssh -L 16006:127…

java:pdfbox 删除扫描版PDF中文本水印

官网下载 https://pdfbox.apache.org/download.html下载 pdfbox-app-3.0.3.jar cd D:\pdfbox 运行 java -jar pdfbox-app-3.0.3.jar java -jar pdfbox-app-3.0.3.jar Usage: pdfbox [COMMAND] [OPTIONS] Commands:debug Analyzes and inspects the internal structu…

RTSP协议讲解

1.RTSP协议 rtsp,英文全称 Real Time Streaming Protocol,RFC2326,实时流传输协议,是 TCP/IP 协议体系中的一个应用层协议。 RTSP 交互流程 1)OPTIONS C--->S 客户端向服务器端发现 OPTIONS,请求可用…

JVM(Java Virtual Machine) 详解

1. JVM 内存区域划分 一个 Java 写的程序,跑起来就得到了一个 Java 进程(资源分配的基本单位) JVM 上面运行的字节码指令 1) 程序计数器(比较小的空间),保存了下一条要执行的指令的地址 这个不是 CPU 的…

API接口开发系列文章:构建高效、安全与可扩展的API服务

前言 在当今的数字化时代,API(应用程序编程接口)已成为连接不同系统、服务和应用的核心桥梁。无论是企业内部的数据交互,还是面向第三方的服务开放,API都扮演着至关重要的角色。本系列文章将深入探讨API接口开发的各个…

两名大学生利用Meta的智能眼镜展示了一项令人震惊的技术,能够实时“人肉”他人的身份信息

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

每日一练:地下城游戏

174. 地下城游戏 - 力扣(LeetCode) 题目要求: 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔…

第十二届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第二套)

一.题目分析 (1).题目 (2).题目分析 1.按键功能分析 a.B1界面切换 b.B2每次按下R加2 c.B3每次按下R减2 d.LED控制按键 2.信号输出功能分析 a.PA7信号输出-----信号的输出就需要使用到输入捕获和输出比较功能 b.输出信号的…

云原生(四十四) | 远程连接ECS服务器

文章目录 远程连接ECS服务器 一、自带连接工具连接ECS云服务器 二、为什么要使用远程连接工具 三、远程连接ECS服务器四要素 1、用户名 密码 2、IP地址(公网IP) 3、SSH端口号 4、阿里云安全组 四、使用MobaXterm远程连接ECS云服务器 五、ECS云…

前端练习小项目 —— 让图片变得更 “色”

前言:相信读者在学习完了HTML、CSS和JavaScript之后已经想要迫不及待的想找一个小型的项目来练练手,那么这篇文章就正好能满足你的 “需求”。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 在开始学习…

【隐私计算篇】多方安全计算之函数秘密共享(FSS)

1. 函数秘密共享(FSS)定义 秘密共享是一种将一个值拆分为多个份额的方法,形式有多种,可以参考《安全多方计算(MPC)矩阵乘法算子的原理分析》。这里主要提及加法秘密共享,使得:这些份额可以重新组合以还原出秘密值;任…

HTMLCSS练习

1) 效果如下 2) 代码如下 2.1) HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conte…

IPS和IDS有啥区别

在网络安全领域&#xff0c;入侵检测系统 (IDS) 和入侵防御系统 (IPS) 是两种关键的技术&#xff0c;旨在保护网络免受各种威胁。这两者尽管名字相似&#xff0c;但在功能、配置、以及应用场景等方面都有着显著的差异。 入侵检测系统 (IDS) IDS 是一种被动监控系统&#xff0c…

自建动态IP代理为何无法使用及解决方法

在网络使用中&#xff0c;有时候我们自建动态IP代理来实现一些特定的需求&#xff0c;例如访问受限内容或保护隐私。然而&#xff0c;有时我们会遇到无法使用的情况。本文将探讨无法使用的可能原因&#xff0c;并提供相应的解决方法。 1. 可能原因 a. 网络配置问题 自建动态I…

Chromium 关闭 Google Chrome 后继续运行后台应用功能分析c++

此功能允许关闭 Google Chrome 后继续运行后台&#xff0c;控制此功能的开关是 // Set to true if background mode is enabled on this browser. //更改此值可以修改默认开启关闭 inline constexpr char kBackgroundModeEnabled[] "background_mode.enabled"; …

Python爬虫(五)--爬虫库的使用(Python Crawler (5) - Use of Crawler Libraries)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

如何解决在 nextjs 中使用 sequelize 连接 mysql 报错:Please install mysql2 package manually

解决方案 手动设置 dialectModule 的值为 mysql2。增加 dialectModule 配置即可。 import mysql2 from mysql2 import { Sequelize } from sequelizeconst { DB_DATABASE, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_LOGGING, DB_POLL_MAX, DB_POLL_MIN, DB_POLL_ACQUIRE, …

Android Framework(八)WMS-窗口动效概述

文章目录 动画简述本地、远端动画的定义什么是“leash”图层“leash”图层的命令与创建 Winscope流程小结 动画流程概览分析Activity启动app_transition 动画的主要事件触发动画执行的套路动画真正执行动画的结束回调触发远端动画的Target 动画简述 1、动画的原理也是利用了视觉…

vue3 + Ant design vue formItem 无法使用嵌套的form表单校验

文章目录 前言一、背景在这里插入代码片二、操作步骤1.复现前的准备工作&#xff08;1&#xff09;vue版本和ant design vue 版本&#xff08;2&#xff09;任意页面的代码 2.解决问题3.自定义表单校验的代码 总结 前言 提示&#xff1a; 一、背景在这里插入代码片 背景&…