11.什么档次的原型模式和我写的一样

news2024/11/24 2:53:13

在这里插入图片描述
在《生化危机》系列电影中,克隆人是个频频出现的话题。保护伞公司为了需求复制出另一个战力相当的战士Alice,不惜克隆成百上千个Alice,然而直到最后,非但没有真正克隆出另一个完美的Alice,就连Alice自己也被证实是保护伞董事的一个克隆人。

克隆人一直是饱含伦理争议的话题,但是在软件设计领域,克隆思想却很受欢迎。软件旨在用程序替代人工去做重复性的工作。归根结底,“懒”是推动软件发展的重要助力,原型模式就是克隆思想的重要应用之一。


一言

原型实例指定创建对象的种类,通过拷贝这些原型创建新的对象。


概述

原型模式是一种创建型设计模式,它允许一个对象再创建一个可定制的对象而无需知道如何创建的细节。就像爱丽丝直到最后才指导自己也是克隆人一样,实例本身是不关注
创建实例的细节的。


原理

通过将一个原型对象传给要发动创建的对象,要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即bean.clone()。
在这里插入图片描述


欢迎来到保护伞公司

在这里插入图片描述

职员7568你好,欢迎你加入保护伞公司,徐江博士交给你的第一个任务是,编写代码,复制十个爱丽丝,加油!

循规蹈矩的豪赌

小职员7568稍加思索便写出了如下代码:

反例代码

Alice原型

public class Alice{
    private String name;
    private int age;
    private String skill;

    public Sheep(String name, int age, String skill) {
        this.name = name;
        this.age = age;
        this.skill= skill;
    }
    
	//setter & getter
	
    @Override
    public String toString() {
        return "Alice{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", skill='" + skill+ '\'' +
                '}';
    }

驱动机

public class Client {
    public static void main(String[] args) {
        Alice alice= new Alice ("alice", 18, "极强的战斗天赋");
        Alice alice1= new Alice ("alice", 18, "极强的战斗天赋");
        Alice alice2= new Alice ("alice", 18, "极强的战斗天赋");
        Alice alice3= new Alice ("alice", 18, "极强的战斗天赋");
        Alice alice4= new Alice ("alice", 18, "极强的战斗天赋");

        System.out.println(alice);
        System.out.println(alice1);
        System.out.println(alice2);
        System.out.println(alice3);
        System.out.println(alice4);
    }
}

不一会,职员7568就高呼自己完成了任务。
徐江博士看了看代码,吩咐手下,“拖出去喂丧尸,什么档次跟我在一个公司工作?”

在这里插入图片描述
所以,保护伞公司职员-1。

问题分析

那么究竟是什么问题导致博士那么生气呢?
首先,要肯定上述代码的优势,简单易操作。但是,在创建新对象的时候总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率会及低。而且每一次都需要重新初始化对象,灵活性太低。

浅拷贝

“老,老板,我有一个不太成熟的思路,不知道当讲不当讲”,职员7569瑟瑟发抖。
“ 讲!”
“Java中Object类是所有类的根类,Object类提供了一个clone()方法,该方法可以将一个Java对象复制一份,但是需要实现clone的Java类必须要实现一个接口cloneable该接口表示该类能够复制且具有复制的能力。通过这种方式,或许…”
徐博士听着这段构想,嘴角露出了不易察觉的微笑:
“很好,但是我有一个要求,我要让这些爱丽丝们做朋友”

代码实现

public class Alice implements Cloneable{
    private String name;
    private int age;
    private String skill;
    public Alice friend;

    public Alice (String name, int age, String skill) {
        this.name = name;
        this.age = age;
        this.skill= skill;
    }
    
    @Override
    protected Object clone(){
        Alice alice = null;
        try {
            alice = (Alice ) super.clone();
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        return alice ;
    }
                               
    @Override
    public String toString() {
        return "Alice{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", skill='" + skill+ '\'' +
                '}';
    }
}

徐博士的检查

徐博士看了看代码,继续吩咐手下,“拖出去,喂丧尸,什么档次跟我待一个公司。”
职员7569高呼:“我不服,我的代码有什么问题?”
徐博士看了看他涨红的面庞,缓缓的将Alice实例的friend属性的哈希值打印了出来,小职员呆住了,再没有了一丝力气。

在这里插入图片描述
保护伞公司职员-1

在实体属性发生变更时,原型模式可以以很小的改动代价实现对象的拷贝。但是,上述实现的克隆并不会将本体的对象属性做到真正意义的克隆,只是将对象的引用复制了多份,所以我们称之为浅克隆。

深拷贝

职员7570汗流浃背了,因为下一个就轮到他来解决这个问题,他拼命的思考,终于,他起身了。
“博士,我想到了。我们复制对象的所有基本数据类型的成员变量值,为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象进行拷贝。”
徐博士抬头看了看这个少年:“继续”
小职员咽了咽口水:“对于深拷贝的实现方式,我想可以通过重写clone方法…或者 ,或者通过对象实例化实现深拷贝。”
徐博士又深深的看了一言面前这个侃侃而谈的少年:“看来你不是个草包,写写看看吧。”
在这里插入图片描述

代码实现

public class DeepCloneAbleTarget implements Serializable,Cloneable{
    private static final long serivalVersionID = 1L;
    private String cloneName;
    private String cloneClass;
    public DeepCloneAbleTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class DeepProtoType implements Serializable,Cloneable {
    public String name;
    public DeepCloneAbleTarget deepCloneAbleTarget;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        deep =super.clone();
        DeepProtoType deepProtoType  =(DeepProtoType) deep;
        deepProtoType.deepCloneAbleTarget = (DeepCloneAbleTarget) deepCloneAbleTarget.clone();
        return deepProtoType;
    }
    public Object deepClone(){
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepProtoType copyObj = (DeepProtoType) ois.readObject();
            return copyObj;
        }catch (Exception e){
            System.err.println(e.getMessage());
            return null;
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。不用重新初始化对象,而是动态地获得对象运行时的状态。如果原始对象发生变化(增加或者减少属性),其它克隆对象的也会发生相应的变化无需修改代码。

但是在实现深克隆的时候可能需要比较复杂的代码。同时,需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源代码,违背了ocp原则。

好啦,今天在保护伞公司的打工之旅就到此为止,祝各位好运。


关注我,共同进步,每周至少一更。——Wayne

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

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

相关文章

华为OD机试之阿里巴巴找黄金宝箱(IV) C++

题目背景 贫如洗的椎夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0-N的箱子,每个箱子上面有一人数字,箱子排列成一个环,编号最大的箱子的下一个是编号为0的箱子。请输出每个箱了贴的数字之…

REVIT二次开发万能刷

将这两个参数赋予其他参数 步骤2 将来做个可以调控的版本 using System; using System.Collections.Generic; using System.Lin

常用界面设计组件 —— 数字输入和显示组件

2.3 数字输入和显示组件2.3.1 QSpinBox 与 QDoubleSpinBox2.3.2其它数值输入和显示组件 2.3 数字输入和显示组件 2.3.1 QSpinBox 与 QDoubleSpinBox QSpinBox用于整数的显示和输入,一般显示十进制 数,也可以显示二进制、十六进制数,而且可以…

基于SpringBoot的智慧社区居家养老健康管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

Shell脚本------变量

目录 一、shell脚本的变量 1、shell脚本的变量是什么? 2、变量的作用 3、变量作用范围 3.1、临时设置 3.2永久设置,需要在/etc/profile文件里添加 4、删除变量 5、变量基础 6、变量命名要求 7、特殊符号 8、整数运算 9、expr算术表达式 二、…

如何在WordPress网站中添加多语言搜索(2种简单方法)

您想在WordPress网站中添加多语言搜索吗? 如果您有一个多语言 WordPress 网站,那么添加多语言搜索功能可以帮助用户通过使用自己的语言进行搜索来更快地找到信息。 在本文中,我们将向您展示如何在 WordPress 中轻松添加多语言搜索&#xff…

“深入理解RabbitMQ交换机的原理与应用“

深入理解RabbitMQ交换机的原理与应用 引言1. RabbitMQ交换机简介介绍1.1 什么是RabbitMQ?1.1.1 消息中间件的作用1.1.2 RabbitMQ的特点和优势 1.2 RabbitMQ的基本概念1.2.1 队列1.2.2 交换机1.2.3 路由键 1.3 交换机的作用和分类1.3.1 直连交换机(direct…

32、WEB攻防——通用漏洞文件上传二次渲染.htaccess变异免杀

文章目录 一、点过滤二、文件删除三、二次渲染四、.htaccess五、过滤php关键函数 一、点过滤 不能写带文件后缀的文件名;IP转数字 二、文件删除 文件依据规则进行删除,删除有两种删除的类型: 什么文件都删除,条件竞争进行绕过…

linux zabbix监控

zabbix总结 zabbix-server 10051 zabbix-agent 10050 zabbix-proxy 10051 1.监控项(模板):获取监控数据 #模板直接链接到新的主机 2.触发器:设置一个值 在非合理区间报警 3.动作:可以帮忙发送通知(告…

深入理解Python循环嵌套

循环嵌套是一种常见的编程技巧,它可以用于处理多维数据结构、模拟多层逻辑等场景。本文将深入探讨Python中的循环嵌套,包括基本语法、应用场景以及一些最佳实践。 循环嵌套的基本语法 在Python中,循环嵌套指的是在一个循环语句的内部再嵌套另…

Microsoft Remote Desktop for Mac(远程桌面连接)激活版

Microsoft Remote Desktop是一款由微软开发的远程桌面连接工具,它允许用户从另一台计算机或移动设备远程连接到Windows桌面或服务器。 以下是该软件的一些主要特点和功能: 跨平台支持:Microsoft Remote Desktop支持Windows、macOS、iOS和Andr…

蓝桥杯(C++ 最大开支 优先队列)

优先队列: 蓝桥杯(C 整数删除 优先队列 )-CSDN博客 思路: 1、每个人依此选择项目,每个人选项目时都(选择当下花费增加最多的项目),若项目i的门票价格为kxb,那么增加一个…

爬取的数据可以入表吗?怎样入表?

合规是数据入表的前提。当前爬虫数据是非常敏感的,因为爬虫极容易造成两大不合规的问题:一是没有经过个人同意获取数据,二是爬取的数据里可能含有个人敏感信息也是一个问题。现在法律对于这部分非常严苛,如果企业里有50条未获得授…

RHCE【报警脚本】

要求如下: 根分区剩余空间小于20% 发送告警邮件给自己 配合crond每5分钟检查一次脚本 报警脚本的具体实现如下: #安装mailx(邮件服务包)[rootlocalhost ~]# yum install mailx #编辑邮件系统文件[rootlocalhost ~]# vim /etc/mail.rc#首先注…

关于在Ubuntu20.04(ROS1 noetic)中使用catkin_make编译时发生的与pyhton版本不兼容的问题解决办法

今天在另外一台电脑上操作复现【ROS建模:一起从零手写URDF模型】这个博客时,发生了一些问题,特此记录下来 【ROS建模:一起从零手写URDF模型】链接:https://blog.csdn.net/qq_54900679/article/details/135726348?spm…

CodeWave智能开发平台-3--采购管理系统搭建完整版

摘要 本文是网易数帆CodeWave智能开发平台系列的第15篇,主要介绍了基于CodeWave平台文档的新手入门进行学习,实现一个完整的应用-采购管理系统。 CodeWave智能开发平台-3–采购管理系统搭建完整版 CodeWave参考资源 网易数帆CodeWave开发者社区课程中…

JFinal项目搭建

JFinal项目搭建 JFinal项目搭建 JFinal项目搭建 首先创建maven项目&#xff1a; 删掉报错的jsp页面&#xff1a; 在pom.xml中加入坐标&#xff1a; <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-undertow</artifactId>…

【Redis】内存淘汰策略和过期删除策略

一、前言 Redis是一个内存键值对数据库&#xff0c;所以对于内存的管理尤为重要。Redis内部对于内存的管理主要包含两个方向&#xff0c;过期删除策略和数据淘汰策略。由于内存有限&#xff0c;缓存系统必须遵循一些淘汰策略来删除一些不再需要的键&#xff0c;以便为新键腾出…

【学习】FPN特征金字塔

论文&#xff1a;Feature Pyramid Networks for Object Detection &#xff08;CVPR 2016) 参考blog&#xff1a;https://blog.csdn.net/weixin_55073640/article/details/122627966 参考视频讲解&#xff1a;添加链接描述 卷积网络中&#xff0c;深层网络容易响应语义特征&am…

java对代码进行性能分析

使用Instant对象来完成 关键代码: 获取当前时间 Instant now Instant.now(); 获取当前时间距离1970-01-01 00:00:00的秒数 now.getEpochSecond() 完整测试代码 Scanner sc new Scanner(System.in);Instant now1 Instant.now();System.out.println("请随便输个东西:…