网站数据库订购/最新疫情消息

网站数据库订购,最新疫情消息,邦利博客网站怎么做的,固安做网站的目录 一、 啥是原型模式?二、 为什么要用原型模式?三、 原型模式怎么实现?四、 原型模式的应用场景五、 原型模式的优点和缺点六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式&#xf…

在这里插入图片描述

目录

    • 一、 啥是原型模式?
    • 二、 为什么要用原型模式?
    • 三、 原型模式怎么实现?
    • 四、 原型模式的应用场景
    • 五、 原型模式的优点和缺点
    • 六、 总结

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解抽象工厂模式请看: (三)趣学设计模式 之 抽象工厂模式!

这篇文章带你详细认识一下设计模式中的原型模式

一、 啥是原型模式?

原型模式,说白了,就是“山寨”! 🤣 你有一个宝贝,不想自己辛辛苦苦再做一个,就找个复印机(克隆方法),咔嚓一下,复制一个一模一样的出来!

  • 对象的创建成本很高: 就像造火箭 🚀,太费劲了,不如复制一个!
  • 需要创建大量相似对象: 就像克隆羊 🐑,要一大堆一样的羊,一个个生太慢了!
  • 希望隐藏对象的创建细节: 就像做菜 🍳,你只想吃,不想知道怎么做的!

二、 为什么要用原型模式?

用原型模式,好处多多:

  • 省钱省力: 不用重复造轮子 🚗,直接复制,省时省力!
  • 灵活多变: 想复制啥就复制啥,不用提前定好,很灵活!
  • 简单易懂: 不用管对象怎么创建的,直接复制就行,代码更简单!
  • 避免麻烦: 不用创建一堆乱七八糟的子类,省心!

三、 原型模式怎么实现?

原型模式主要有两种“山寨”方法:

  • 浅拷贝(Shallow Copy)
  • 深拷贝(Deep Copy)

实现原型模式的关键点

  • Cloneable 接口: 就像一个“允许复制”的标签 🏷️,贴上这个标签,才能被复印!
  • Object 类的 clone() 方法: 就像复印机的基本功能,只能复印表面信息(浅拷贝)!
  • 重写 clone() 方法: 就像升级复印机,让它可以复印所有信息(深拷贝)!

1.浅拷贝(Shallow Copy):只复制表面! 🤏

浅拷贝就像复印身份证 🪪,你复印了一张身份证,上面的名字、地址都一样,但是里面的芯片还是原来的那个。如果原来的身份证信息变了,复印件也会跟着变!

// 1. 定义原型接口 (Cloneable 是 Java 内置的接口)
interface Prototype extends Cloneable {Prototype clone(); // 克隆方法
}// 2. 定义具体原型类
class Sheep implements Prototype {private String name;private int age;private Address address; // 引用类型属性public Sheep(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(String city) {this.address.setCity(city);}@Overridepublic Sheep clone() {try {// 浅拷贝:直接调用 Object 类的 clone() 方法return (Sheep) super.clone();} catch (CloneNotSupportedException e) {System.out.println("克隆失败! 😭");return null;}}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +", address=" + address +'}';}
}// 地址类 (引用类型)
class Address {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}@Overridepublic String toString() {return "Address{" +"city='" + city + '\'' +'}';}
}// 3. 客户端使用
public class Client {public static void main(String[] args) {// 创建原型对象Address address = new Address("北京");Sheep originalSheep = new Sheep("多莉", 3, address);// 克隆原型对象Sheep clonedSheep = originalSheep.clone();// 打印原始对象和克隆对象System.out.println("原始羊: " + originalSheep);System.out.println("克隆羊: " + clonedSheep);// 修改原始对象的引用类型属性originalSheep.setAddress("上海");// 再次打印原始对象和克隆对象System.out.println("修改后的原始羊: " + originalSheep);System.out.println("修改后的克隆羊: " + clonedSheep);}
}

代码解释:

  • Prototype:原型接口,定义了克隆方法。
  • Sheep:具体原型类,实现了 Prototype 接口,表示羊。
  • clone():克隆方法,用于创建对象的副本。
  • Address:地址类,作为 Sheep 类的引用类型属性。

输出结果:

原始羊: Sheep{name='多莉', age=3, address=Address{city='北京'}}
克隆羊: Sheep{name='多莉', age=3, address=Address{city='北京'}}
修改后的原始羊: Sheep{name='多莉', age=3, address=Address{city='上海'}}
修改后的克隆羊: Sheep{name='多莉', age=3, address=Address{city='上海'}}

分析:

可以看到,修改原始羊的地址后,克隆羊的地址也跟着改变了!这是因为浅拷贝只复制了地址的“指针”,原始羊和克隆羊指向的是同一个地址,所以一个变了,另一个也跟着变!

2. 深拷贝(Deep Copy):彻底复制! 💯

深拷贝就像克隆一只完整的羊 🐑,你克隆了一只羊,它有自己的名字、年龄和地址,和原来的羊完全没有关系。即使原来的羊死了,克隆羊还是活蹦乱跳的!

import java.io.*;class Sheep implements Prototype, Serializable { // 注意实现 Serializable 接口private String name;private int age;private Address address;public Sheep(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic Sheep clone() {try {// 使用序列化和反序列化实现深拷贝ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (Sheep) ois.readObject();} catch (Exception e) {System.out.println("克隆失败! 😭");return null;}}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +", address=" + address +'}';}
}class Address implements Serializable { // 注意实现 Serializable 接口private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}@Overridepublic String toString() {return "Address{" +"city='" + city + '\'' +'}';}
}public class Client {public static void main(String[] args) {// 创建原型对象Address address = new Address("北京");Sheep originalSheep = new Sheep("多莉", 3, address);// 克隆原型对象Sheep clonedSheep = originalSheep.clone();// 打印原始对象和克隆对象System.out.println("原始羊: " + originalSheep);System.out.println("克隆羊: " + clonedSheep);// 修改原始对象的引用类型属性address.setCity("上海");// 再次打印原始对象和克隆对象System.out.println("修改后的原始羊: " + originalSheep);System.out.println("修改后的克隆羊: " + clonedSheep);}
}

注意: 使用序列化和反序列化实现深拷贝,需要确保对象及其所有属性都实现了 Serializable 接口。

输出结果:

原始羊: Sheep{name='多莉', age=3, address=Address{city='北京'}}
克隆羊: Sheep{name='多莉', age=3, address=Address{city='北京'}}
修改后的原始羊: Sheep{name='多莉', age=3, address=Address{city='上海'}}
修改后的克隆羊: Sheep{name='多莉', age=3, address=Address{city='北京'}}

分析:

可以看到,修改原始羊的地址后,克隆羊的地址没有改变!这是因为深拷贝复制了地址的所有信息,原始羊和克隆羊拥有不同的地址,所以一个变了,另一个不会受到影响!

四、 原型模式的应用场景

  • 游戏开发: 游戏里的怪物 👾,不用一个个设计,复制几个改改属性就行!
  • 文档编辑器: 文档的模板 📄,复制一份改改,就能生成新的文档!
  • 图形编辑器: 图形对象 🖼️,复制一份改改颜色、大小,就能得到新的图形!
  • 配置管理: 软件的配置 ⚙️,复制一份改改,就能适应不同的环境!
  • 报表生成: 报表的模板 📊,复制一份改改数据,就能生成不同的报表!

五、 原型模式的优点和缺点

优点:

  • 省钱省力: 不用重新创建对象,直接复制,就像复制粘贴一样简单,大大提高了效率!
  • 隐藏秘密: 客户端不用知道对象是怎么创建的,只需要知道怎么复制就行,保护了对象的内部结构!
  • 灵活应变: 可以在运行时动态地复制对象,想复制啥就复制啥,非常灵活!
  • 减少麻烦: 不用创建一堆子类,避免了代码的膨胀,让代码更简洁!

缺点:

  • 复制很麻烦: 特别是深拷贝,要复制对象的所有信息,就像搬家一样,很麻烦!
  • 破坏隐私: 为了复制对象,可能需要访问对象的私有属性,就像偷看别人的日记一样,破坏了对象的封装性!
  • 需要贴标签: 在 Java 中,需要实现 Cloneable 接口才能被复制,就像需要贴上“允许复制”的标签,有点麻烦!
  • 可能出错: 有时候复制操作可能不会执行构造函数,就像克隆羊没有灵魂一样,可能会导致对象的状态不正确!

六、 总结

  • 原型模式就是“山寨”大法,通过复制现有对象来创建新对象!
  • 适用于需要大量相似对象、对象创建成本高、需要隐藏对象创建细节的场景!
  • 有两种“山寨”方法:浅拷贝和深拷贝!
  • 浅拷贝只复制表面信息,深拷贝复制所有信息!
  • 要根据实际情况选择合适的“山寨”方法!
  • 使用原型模式需要注意一些问题,比如破坏封装性、可能出错等等!

希望这篇文章能让你彻底理解原型模式! 👍
看完请看:(五)趣学设计模式 之 建造者模式!

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

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

相关文章

完美解决:.vmx 配置文件是由 VMware 产品创建,但该产品与此版 VMware Workstation 不兼容

参考文章:该产品与此版 VMware Workstation 不兼容,因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时,可能会遇到以下报错: 此问题常见于以下场景: 从其他 VMware 版本(如 ESX…

从零开始的网站搭建(以照片/文本/视频信息通信网站为例)

本文面向已经有一些编程基础(会至少一门编程语言,比如python),但是没有搭建过web应用的人群,会写得尽量细致。重点介绍流程和部署云端的步骤,具体javascript代码怎么写之类的,这里不会涉及。 搭…

【Java项目】基于SpringBoot的【高校校园点餐系统】

【Java项目】基于SpringBoot的【高校校园点餐系统】 技术简介:采用Java技术、MySQL数据库、B/S结构实现。 系统简介:高校校园点餐系统是一个面向高校师生的在线点餐平台,主要分为前台和后台两大模块。前台功能模块包括(1&#xff…

Django check_password原理

check_password 是 Django 提供的一个用于密码校验的函数,它的工作原理是基于密码哈希算法的特性。 Django 的 make_password 函数在生成密码哈希时,会使用一个随机的 salt(盐值)。这个 salt 会与密码一起进行哈希运算&#xff0…

Vulnhun靶机-kioptix level 4-sql注入万能密码拿到权限ssh连接利用mysql-udf漏洞提权

目录 一、环境搭建信息收集扫描ip扫描开放端口扫描版本服务信息指纹探测目录扫描 二、Web渗透sql注入 三、提权UDF提权修改权限 一、环境搭建 然后选择靶机所在文件夹 信息收集 本靶机ip和攻击机ip 攻击机:192.168.108.130 靶机:192.168.108.141 扫描…

PHP 会话(Session)实现用户登陆功能

Cookie是一种在客户端和服务器之间传递数据的机制。它是由服务器发送给客户端的小型文本文件,保存在客户端的浏览器中。每当浏览器向同一服务器发送请求时,它会自动将相关的Cookie信息包含在请求中,以便服务器可以使用这些信息来提供个性化的…

推荐几款SpringBoot项目手脚架

作为程序员、一般需要搭建项目手脚架时、都会去Gitee或Github上去找、但是由于Github在国内并不稳定、所以就只能去Gitee去上查找。 不同语言检索方式不一样、但是也类似。 Gitee WEB应用开发 / 后台管理框架 芋道源码 ELADMIN 后台管理系统 一个基于 Spring Boot 2.7.1…

医院安全(不良)事件上报系统源码,基于Laravel8开发,依托其优雅的语法与强大的扩展能力

医院安全(不良)事件上报系统源码 系统定义: 规范医院安全(不良)事件的主动报告,增强风险防范意识,及时发现医院不良事件和安全隐患,将获取的医院安全信息进行分析反馈,…

H3C交换机路由器防火墙FTP/TFTP服务器搭建。

软件介绍。 3CDaemon 2.0 - Download 3CDaemon 是一款集成了多种网络服务功能的工具软件,主要用于网络管理和文件传输,支持TFTP、FTP、Syslog等多种协议,广泛应用于网络设备的配置和管理。 1. 主要功能 TFTP服务器:支持TFTP协议…

【网络安全 | 漏洞挖掘】账户接管+PII+原漏洞绕过

文章目录 前言正文前言 本文涉及的所有漏洞测试共耗时约三周,成果如下: 访问管理面板,成功接管目标列出的3000多家公司。 获取所有员工的真实指纹、机密文件及个人身份信息(PII)。 绕过KYC认证,成功接管电话号码。 绕过此前发现的漏洞。 正文 在测试目标时,我发现了一…

深度学习学习笔记(34周)

目录 摘要 Abstracts 简介 Hourglass Module(Hourglass 模块) 网络结构 Intermediate Supervision(中间监督) 训练过程细节 评测结果 摘要 本周阅读了《Stacked Hourglass Networks for Human Pose Estimation》&#xf…

JVM类文件结构深度解析:跨平台基石与字节码探秘

目录 一、类文件:Java生态的通用语言 1.1 字节码的桥梁作用 1.2 类文件核心优势 二、类文件二进制结构剖析 2.1 整体结构布局 2.2 魔数与版本控制 2.3 常量池:类文件的资源仓库 2.4 访问标志位解析 三、核心数据结构详解 3.1 方法表结构 3.2 …

wps中zotero插件消失,解决每次都需要重新开问题

参考 查看zotero目录 D:\zotero\integration\word-for-windows 加载项点击 dotm即可 长期解决 把dom 复制到 C:\Users\89735\AppData\Roaming\kingsoft\office6\templates\wps\zh_CN还是每次都需要重新开的话 重新加载一下

List 接口中的 sort 和 forEach 方法

List 接口中的 sort 和 forEach 方法是 Java 8 引入的两个非常实用的函数,分别用于 排序 和 遍历 列表中的元素。以下是它们的详细介绍和用法: sort 函数 功能 对列表中的元素进行排序。 默认使用自然顺序(如数字从小到大,字符…

GitCode 助力至善云学:构建智慧教育平台

项目仓库: 前端:https://gitcode.com/Fer_Amiya/vue-ZhiShanYunXue-Client 后端:https://gitcode.com/Fer_Amiya/go-ZhiShanYunXue-Server 突破传统教学困境,探索教育新解法 传统教学的习题讲评环节,教师面临着难以…

nnUNet V2修改网络——加入MultiResBlock模块

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 MultiRes Block 是 MultiResUNet 中核心组件之一,旨在解决传统 U-Net 在处理多尺度医学图像时的局…

HarmonyOS 开发套件 介绍——下篇

HarmonyOS 开发套件 介绍——下篇 在HarmonyOS的生态中,开发套件作为支撑整个系统发展的基石,为开发者提供了丰富而强大的工具和服务。本文将深入继续介绍HarmonyOS SDK、ArkCompiler、DevEco Testing、AppGallery等核心组件,帮助开发者全面掌…

小怿学习日记(七) | Unreal引擎灯光架构

灯光的布局对于HMI场景中车模的展示效果有着举足轻重的地位。本篇内容将简单介绍ES3.1的相关知识,再深入了解Unreal引擎中车模的灯光以及灯光架构。 一、关于ES3.1 1.1 什么是ES3.1 ES3.1这个概念对于美术的同学可能比较陌生,ES3.1指的是OpenGL ES3.1&…

【洛谷排序算法】P1012拼数-详细讲解

这道题本质上是通过确定数字的拼接顺序来得到最大拼接数,虽然主要思路是利用字符串及其比较规则来实现,但也可以基于数组结合一些转换操作来解决,以下是大致思路和代码示例: 【算法思路】 首先将输入的数字存储在数组中。然后自…

2025前端框架最新组件解析与实战技巧:Vue与React的革新之路

作者:飞天大河豚 引言 2025年的前端开发领域,Vue与React依然是开发者最青睐的框架。随着Vue 3的全面普及和React 18的持续优化,两大框架在组件化开发、性能优化、工程化支持等方面均有显著突破。本文将从最新组件特性、使用场景和编码技巧三…