趣解设计模式之《小王的学习秘籍》

news2024/11/26 17:39:52

〇、小故事

小王是学校的学霸,凭借着自己的天赋以及对于学习的刻苦,每次考试都能排到年级第一名。但是,他所在的班级总成绩却不高,在所有班级中,属于中游水平。老师希望通过小王的贡献,能否帮助整个班级同学分数都有一个提升

老师跟小王提出了这个建议后,小王也很痛快就答应了。然后,利用周六和周日两天时间,将本周的一些重点和难点知识,以及他自己对于某些知识的理解小窍门都总结了出来,一共写了20多页的总结笔记

周一上学,大家都争着抢着去借阅小王的“学习秘籍”,甚至很多同学都开始手抄了起来。20多页的内容,纯手抄得需要好长时间,这时候,小王跟同学们说,“大家别手抄了,太麻烦了,我去楼下的打印社,给同学们每人打印一份”。

就这样,大概用了20分钟不到的时间,就给全班50多名同学每人打印了一份。大家开心的复习了起来,最后,通过小王同学每周总结的“学习秘籍”,他们班级的总成绩跃升成为了年级第一,大家开心极了!

通过上面的例子我们发现,如果大家手抄一份学习秘籍,假设每人平均需要1个小时的话,那么班级50名同学,都抄完就需要50个小时了。但是,如果复印的话,一页50份如果需要1分钟,那么20页需要20分钟就可以了。同样的创建50份学习秘籍,从50小时缩短为20分钟,这就是我们今天要介绍的设计模式的魅力——原型模式

一、模式定义

原型模式Prototype Pattern

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。也就是说,这种不通过new关键字来产生一个对象,而是通过对象复制(Java中的clone反序列化)来实现的模式,就叫做原型模式。

二、模式类图

原型模式的类图比较简单,只需要clone方法和实现clone方法即可,客户端如果需要去创建实例,则通过调用clone就可以了。具体类图如下所示:

三、原型模式的应用场景

3.1> 原型模式的特点

性能优良

原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环内产生大量的对象时,原型模式可能更好地体现其优点。

逃避构造函数的约束

直接在内存中拷贝,构造函数是不会执行的。

3.2> 原型模式的使用场景

资源优化场景

类初始化需要消耗非常多的资源,这个资源包括数据、硬件资源等等。

性能和安全要求的场景

通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时则可以使用原型模式。

一个对象多个修改者的场景

一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用

四、原型模式的注意事项

4.1> 构造函数不会被执行

验证通过clone()方法不会触发构造函数的执行Prototype.java

public class Prototype implements Cloneable {
    public static void main(String[] args) {
        Prototype prototype = new Prototype();
        
        /** 通过clone方法创建的Prototype对象不会执行构造方法 */
        Prototype clonePrototype = prototype.clone();
    }

    public Prototype() {
        System.out.println("-----Prototype的构造方法被执行了!-----");
    }

    @Override
    protected Prototype clone() {
        try {
            return (Prototype)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

执行结果如下所示

-----Prototype的构造方法被执行了!-----

Process finished with exit code 0

4.2> 浅拷贝&深拷贝

实现浅拷贝与深拷贝Prototype1.java

@Data
public class Prototype1 implements Cloneable {

    private String name;

    private List<String> arrayList = new ArrayList<>();

    public static void main(String[] args) {
        Prototype1 prototype1 = new Prototype1();
        prototype1.setName("orign object");
        prototype1.setValue("orign object");

        Prototype1 clonePrototype1 = prototype1.clone();
        clonePrototype1.setName("clone object");
        /** 发现添加了执行了clone对象的setValue之后,也修改了prototype1中的arrayList中数据 */
        clonePrototype1.setValue("clone object");
        System.out.println(prototype1);
        System.out.println(clonePrototype1);
    }

    /**
     * 浅拷贝
     * @return
     */
    @Override
    protected Prototype1 clone() {
        try {
            return (Prototype1)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 深拷贝
     * @return
     */
//    @Override
//    protected Prototype1 clone() {
//        Prototype1 prototype1 = null;
//        try {
//            prototype1 = (Prototype1)super.clone();
//            prototype1.setArrayList(new ArrayList<>());
//        } catch (CloneNotSupportedException e) {
//            e.printStackTrace();
//        }
//        return prototype1;
//    }


    public void setValue(String value) {
        this.arrayList.add(value);
    }

    public List<String> getValue() {
        return this.arrayList;
    }
}

执行结果如下所示

Prototype1(name=orign object, arrayList=[orign object, clone object])
Prototype1(name=clone object, arrayList=[orign object, clone object])

Process finished with exit code 0

因为Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝。

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

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

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

相关文章

证券账户可以绑定几张银行卡,可以更换绑定吗

个人账户实现股票量化程序化自动交易&#xff0c;券商有接口&#xff0c;门槛已降低_股票程序交易接口的博客-CSDN博客像上面的例子&#xff0c;如果按照市面上常见的可转债万3或万2不免5&#xff0c;人工操作费率限制&#xff0c;这种情况就不要想&#xff0c;根本没机会&…

返回最大元素的索引 忽略数组中所有的NaN值 numpy.nanargmax()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 返回最大元素的索引 忽略数组中所有的NaN值 numpy.nanargmax() [太阳]选择题 请问代码中第一次执行语句的输出正确的是&#xff1f; import numpy as np a np.array([0,np.nan,2]) print(&…

H264视频压缩格式

H264简介 H.264从1999年开始&#xff0c;到2003年形成草案&#xff0c;最后在2007年定稿有待核实。在ITU的标准里称为H.264, 在MPEG的标准里是MPEG-4的一个组成部分-MPEG-4 Part 10&#xff0c;又叫Advanced Video Codec&#xff0c;因此常常称为MPEG-4AVC或直接叫AVC。 压缩算…

服务器搭建(TCP套接字)-fork版(服务端)

基础版的服务端虽然基本实现了服务器的基本功能&#xff0c;但是如果客户端的并发量比较大的话&#xff0c;服务端的压力和性能就会大打折扣,为了提升服务端的并发性能&#xff0c;可以通过fork子进程的方式&#xff0c;为每一个连接成功的客户端fork一个子进程&#xff0c;这样…

Ansible自动化:简化你的运维任务

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

OpenStack创建云主机并连接CRT

文章目录 OpenStackT版创建云主机并连接CRT命令行操作&#xff08;1&#xff09;创建镜像&#xff08;2&#xff09;创建实例&#xff08;3&#xff09;创建网络创建内网创建外网 &#xff08;4&#xff09;创建安全组&#xff08;5&#xff09;创建路由&#xff08;6&#xff…

如何利用CSS实现三角形、扇形、聊天气泡框

思路 三角形 实现三角形的关键思路是使用 CSS 的 border 属性来创建一个透明的矩形块&#xff0c;并利用边框的透明部分来形成三角形。下面是创建三角形的一般思路&#xff1a; 创建一个 HTML 元素&#xff0c;通常是一个 <div> 元素&#xff0c;用于容纳三角形。 为该…

超低功耗段码LCD液晶显示驱动IC-VKL144A/BQFN48超小体积液晶驱动

产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;TSSOP48/QFN48L 产品年份&#xff1a;新年份 沈先生 135 、547/44,703 原厂&#xff0c;工程服务&#xff0c;技术支持&#xff01; VKL144A/B 概述: VKL144A/B 是一个点阵式存储映射的LCD 驱动器&#xff0c;可…

数据库操作-DML/DQL

数据库操作-DML DML英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进行增、删、改操作。 添加数据&#xff08;INSERT&#xff09; 修改数据&#xff08;UPDATE&#xff09; 删除数据&#xff08;DELETE&#xff09; 增加(ins…

面试题四:请解释一下watch,computed和filter之间的区别

watch与computed、filter&#xff1a; watch:监控已有属性&#xff0c;一旦属性发生了改变就去自动调用对应的方法 computed:监控已有的属性,一旦属性的依赖发生了改变&#xff0c;就去自动调用对应的方法.computed有详细的介绍&#xff0c;移步computed的使用 filter:js中为…

2023 Google 开发者大会 – 惊喜来袭

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 2023 Google 开发者大会 – 惊喜来袭 2023 Google 开发者大会面向开发者和科技爱好者展示最新产品和平台的年度盛会。今年Google大会为大家提供了丰富的学习资源&…

transforms数据预处理【图像增强】 ->(个人学习记录笔记)

文章目录 1. 安装2. transforms——Crop 裁剪2.1 transforms.CenterCrop2.2 transforms.RandomCrop2.3 transforms.RandomResizedCrop2.4 transforms.FiveCrop2.5 transforms.TenCrop 3. transforms——Flip 翻转3.1 transforms.RandomHorizontalFlip3.2 transforms.RandomVert…

Bash脚本学习:AWK, SED

1. AWK AWK 是一种编程语言&#xff0c;设计用于处理文件或数据流中基于文本的数据&#xff0c;或者使用 shell 管道。 可以将 awk 与 shell 脚本结合使用或直接在 shell 提示符下使用。 以上展示使用AWK分别打印第一个位置变量和第二个位置变量。 建立一个文档 csvtest.cs…

【前端知识】Three 学习日志(二)—— 加强三维空间认识

Three 学习日志&#xff08;二&#xff09;—— 加强三维空间认识 一、设置辅助观察坐标系 // 创建3D场景对象Scene const scene new THREE.Scene(); // AxesHelper&#xff1a;辅助观察的坐标系 const axesHelper new THREE.AxesHelper(150); scene.add(axesHelper);二、设…

布局设计和实现:计算器UI【TableLayout、GridLayout】

一、使用TableLayout实现计算器UI 1.新建一个空白项目布局 根据自己的需求输入其他信息 填写完成后&#xff0c;点击Finish即可 2. 设计UI界面 在res/layout文件夹中的XML文件中创建UI界面。在这个XML文件中&#xff0c;您可以使用TableLayout来设计计算器界面。 2.1 创建l…

【PyTorch攻略(1/7)】 张量基本语法

一、说明 Tensor 是一种特殊的数据结构&#xff0c;与数组和矩阵非常相似。在 PyTorch 中&#xff0c;我们使用张量对模型的输入和输出以及模型的参数进行编码。 张量类似于 NumPy 和 ndarray&#xff0c;除了张量可以在 GPU 或其他硬件加速器上运行。事实上&#xff0c;张量和…

Navicat 连接数据库出现1251

原因&#xff1a; MySQL8.0以上版本的加密方式和MySQL5.0的不一样&#xff0c;所以Navicat连接MySQL会报错。 1251 - Client does not support authentication protocol requested by server; consider upgrading MysQl. cdient– 修改远程连接权限 % 可换为自己的电脑ip GRAN…

Spring Boot实现web.xml功能

Spring Boot实现web.xml功能 1. 基于注解实现1.1 组件注册1.2 WebInitParam注解 2. 基于编码实现2.1 Servlet & Filter2.2 Listener 3. 总结 在Spring Boot中&#xff0c;不再需要使用传统的 web.xml 文件来配置web应用的功能&#xff0c;Spring Boot支持通过注解和基于代码…

132.【MySQL_进阶】

MySQL_进阶 (一)、存储引擎1.MySQL体系结构(1).连接层(2).服务层(3).引擎层(4).存储层 2.存储引擎简介(1).查看某张表的数据引擎(2).展示此版本支持的所有存储引擎(3).创建表my_myisam,并指定MyIASM存储引擎(4).存储引擎示列 3.存储引擎 _ Innodb(1).Innodb 介绍(2).Innodb 特点…

展会预告 | 图扑邀您共聚 IOTE 国际物联网展·深圳站

参展时间&#xff1a;9 月 20 日- 22 日 图扑展位&#xff1a;9 号馆 9B 35-1 参展地址&#xff1a;深圳国际会展中心&#xff08;宝安新馆&#xff09; IOTE 2023 第二十届国际物联网展深圳站&#xff0c;将于 9 月 20 日- 22 日在深圳国际会展中心&#xff08;宝安&#xf…