原型模式(设计模式详解)

news2024/11/28 11:50:56

原型模式

描述

原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需从头开始编写代码。

  • 在原型模式中,一个原型对象作为模板,新的对象通过克隆这个原型对象而创建。这样可以避免使用相同的代码来创建相似的对象,同时也可以提高创建对象的效率。通常情况下,原型模式会使用一个原型管理器来存储和管理原型对象,以便在需要的时候进行复制。

  • 原型模式适用于需要创建大量相似对象的场景,如图形编辑器中的图形对象、数据库中的数据对象、网络传输中的数据包等。通过使用原型模式,可以大大提高对象创建的效率和代码复用性。


实现


public class Client {
    public static void main(String[] args) {
        Car car = new Car("丰田", 140000);
        Prototype prototype = new Prototype();
        prototype.registerObj("丰田",car);
        Car cloneCar = prototype.clone("丰田");
        System.out.println(car == cloneCar);
        System.out.println(cloneCar);

    }
}

/**
 * 原型对象
 */
class Prototype {
    //存放实例的map
    private Map<String, Object> prototypeMap;

    public Prototype() {
        this.prototypeMap = new HashMap<>();
    }
    //注册对象
    public void registerObj(String name,Object o){
        prototypeMap.put(name,o);
    }

    public void unRegisterObj(String name){
        prototypeMap.remove(name);
    }

    public Car clone(String name){
        return ((Car)(prototypeMap.get(name))).clone();
    }
}

/**
 * Car继承Cloneable
 */
class Car implements Cloneable{
    private String carName;
    private int price;
    public Car(){

    }
    public Car(String carName, int price) {
        this.carName = carName;
        this.price = price;
    }
    public Car clone(){
        try {
            return (Car) super.clone();
        } catch (CloneNotSupportedException e) {
            return new Car(this.carName,this.price);
        }
    }

    @Override
    public String toString() {
        return "Car{" +
                "carName='" + carName + '\'' +
                ", price=" + price +
                '}';
    }
}

对于对象的拷贝是使用jdk自带的clone,那么就会有个问题,拷贝是属于深拷贝还是浅拷贝呢?

深拷贝:深拷贝(Deep Copy)是指在进行对象复制时,将被复制对象的所有成员变量都复制一份到新的对象中,而不是仅仅复制对象的引用。

浅拷贝:,浅拷贝(Shallow Copy)仅仅复制对象的引用,而不是对象本身的成员变量。因此,如果原对象发生变化,浅拷贝后的新对象也会受到影响。

我们来测试一下。我们把Car修改成以下代码

class Car implements Cloneable{
    private String carName;
    private int price;
    private Object from;
    public Car(){

    }
    public Car(String carName, int price,Object from) {
        this.carName = carName;
        this.price = price;
        this.from = from;
    }
    public Car clone(){
        try {
            return (Car) super.clone();
        } catch (CloneNotSupportedException e) {
            return new Car(this.carName,this.price,this.from);
        }
    }

    @Override
    public String toString() {
        return "Car{" +
                "carName='" + carName + '\'' +
                ", price=" + price +
                '}';
    }

    public String getCarName() {
        return carName;
    }

    public int getPrice() {
        return price;
    }

    public Object getFrom() {
        return from;
    }
}

当克隆后我们比对引用类型的属性

   Car car = new Car("丰田", 140000,new Object());
        Prototype prototype = new Prototype();
        prototype.registerObj("丰田",car);
        Car cloneCar = prototype.clone("丰田");
        System.out.println(cloneCar.getFrom() == car.getFrom());

在这里插入图片描述发现克隆的对象的引用属性和被克隆的对象引用属性的地址一致。

通过以上结论,我们可以知道,jdk的clone为浅拷贝。如果需要深拷贝,我们需要重新自己写一个克隆方法来进行深拷贝。


使用场景

  • 当需要创建的对象具有相同的属性和方法时,但其状态不同,例如游戏中的敌人,它们具有相同的属性和方法,但具有不同的血量、攻击力等状态。

  • 当创建对象的过程非常昂贵或复杂时,例如数据库连接对象、网络连接对象等。在这种情况下,通过复制现有对象,可以避免重复创建对象,从而提高性能。

  • 当需要避免构造函数被反复调用时,例如在某些系统中,构造函数可能会执行一些昂贵的计算或操作,通过使用原型模式,可以避免这些计算或操作被反复执行

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

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

相关文章

MySQL OCP888题解048-letter N in slow query log(慢查询日志里的字母N)

文章目录1、原题1.1、英文原题1.2、中文翻译1.3、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3.1、知识点1&#xff1a;mysqldumpslow - 总结缓慢的查询日志文件4、实验4.1、实验14.1.1、实验目的4.1.2、实验前准备4.1.3、实验步骤4.1.4、实验结论5、总结1、原题 1.1…

dva01-初识

背景 React 本身只是一个 DOM 的抽象层&#xff0c;使用组件构建虚拟 DOM。如果开发大应用&#xff0c;还需要解决一个问题。 通信&#xff1a;React 只提供了一种传参手段&#xff0c;后续数据变化非常麻烦&#xff0c;无法适用于大应用。数据流&#xff1a;每次要更新数据&…

ACE C++网络通信框架深入解析ACE_Message_Block消息类

前言 我所见到最好消息包的接口设计莫过于ACE_Message_Block了。 为什么这样说呢&#xff1f; 对于它的API说明&#xff0c;我最初仅想在它的基础上提供注释说明&#xff0c;而不想多言其它&#xff0c;因为无需多言其他。 不过&#xff0c;后来还是补充两个图&#xff0c;以…

后台搭建常用方式及常用的插件

利用脚手架创建项目 create-vite 是一个快速生成主流框架基础模板的工具,安装后启动预设创建项目 使用NPM&#xff1a; npm create vitelatest 使用Yarn: yarn create vite 使用PNPM: pnpm create vite 开始 | Vite 官方中文文档 create-vue&#xff0c;是 Vue 官方的项目脚…

Flume工作原理 安装配置

目录 简介 主要功能 日志收集 数据处理 工作原理 Flume架构 安装 拷贝压缩包 解压 改名 修改配置文件 安装nc&#xff08;netcat&#xff09; 安装telnet协议 应用 应用一&#xff1a;实时监听 新建netcat-logger.conf文件 开启端口监听方式一 访问主机 开启…

flume安装与配置

目录 flume描述 flume用途 flume基本组件 配置flume 搭建环境&#xff1a; 解压flume安装包将其放入到opt/soft目录 在/opt/soft目录下将apache-flume-1.9.0-bin.tar.gz 改名为flume190 到/opt/soft/flume190/conf目录中将临时配置文件flume-env.sh.template拷贝为配置文…

香港酒店模拟分析项目报告--使用tableau、python、matlab

转载请标记本文出处 软件&#xff1a;tableau、pycharm、关系型数据库&#xff1a;MySQL 数据大量分析考虑电脑性能的情况。 文章目录前言一、爬虫是什么&#xff1f;二、使用tableau数据可视化1.引入数据1.1 制作直方图-各地区酒店数量条形图1.2 各地区酒店均价1.3 价格等级堆…

Idea+maven+spring-cloud项目搭建系列--11-3 dubbo限流和熔断

前言: dubbo 作为rpc 通信组件&#xff0c;在使用过程中&#xff0c;如何避免服务提供端被多个消费端撑爆&#xff0c;消费端如何避免因为服务端的故障造成结果响应超时。 1 服务提供端的限流措施&#xff1a; 1.1 使用 &#xff1a;dubbo.protocol.accepts 参数限制服务端同…

面试热点题:回溯算法之组合 组合与组合总和 III

什么是回溯算法&#xff1f; 回溯算法也可以叫回溯搜索算法&#xff0c;回溯是递归的"副产品",回溯的本质是穷举&#xff0c;然后选出我们需要的数据&#xff0c;回溯本身不是特别高效的算法&#xff0c;但我们可以通过"剪枝"来优化它。 理解回溯算法 回溯…

电脑游戏怎么录屏?其实很简单,只需要简单3步

电脑游戏一直是游戏爱好者最热衷的游戏之一。但是&#xff0c;有时候我们想分享我们在游戏中的精彩时刻&#xff0c;或者记录我们的游戏过程以便后续观看和学习。在这种情况下&#xff0c;录屏就成了必不可少的工具。但是&#xff0c;许多人可能不知道电脑游戏怎么录屏。在本文…

逆向分析——壳

你脑海中的壳是什么 壳在自然界是动物的保护壳&#xff0c;软件同样有保护壳&#xff0c;为了防止破解 也许大海给贝壳下的定义是珍珠&#xff0c;也许时间给煤炭下的定义是钻石 ——沙与沫 壳的由来 在DOS时代&#xff0c;壳一般指的是磁盘加密软件中的一段加密程序 后来发展…

APM新添加UAVCAN设备

简介 UAVCAN是一种轻量级协议,旨在通过CAN总线在航空航天和机器人应用中实现可靠通信。要实现通信&#xff0c;最基本需要data_type_ id, signature、数据结构、设备程序初始化。 添加设备数据结构文件(.uavcan格式) 1.在以下路径添加设备数据结构文件&#xff0c;根据设备类…

三体到底是啥?用Python跑一遍就明白了

文章目录拉格朗日方程推导方程组微分方程算法化求解画图动图绘制温馨提示&#xff0c;只想看图的画直接跳到最后一节拉格朗日方程 此前所做的一切三体和太阳系的动画&#xff0c;都是基于牛顿力学的&#xff0c;而且直接对微分进行差分化&#xff0c;从而精度非常感人&#xf…

Web漏洞-CSRF漏洞

CSRF漏洞介绍&#xff1a;CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;中文名称&#xff1a;跨站请求伪造&#xff0c;是一种劫持用户在当前已登录的Web应用程序上执行非本意操作一种攻击.原理&#xff1a;攻击者利用目标用户的身份&#xff0c;执行某…

基于Stackelberg博弈的光伏用户群优化定价模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

keras学习之回调函数的使用

回调函数 回调函数是一个对象&#xff08;实现了特定方法的类实例&#xff09;&#xff0c;它在调用fit()时被传入模型&#xff0c;并在训练过程中的不同时间点被模型调用可以访问关于模型状态与模型性能的所有可用数据模型检查点&#xff08;model checkpointing&#xff09;…

【SAP PO】X-DOC:SAP PO 接口配置 REST 服务对接填坑记

X-DOC&#xff1a;SAP PO 接口配置 REST 服务对接填坑记1、背景2、PO SLD配置3、PO https证书导入1、背景 &#xff08;1&#xff09;需求背景&#xff1a; SAP中BOM频繁变更&#xff0c;技术人员在对BOM进行变更后&#xff0c;希望及时通知到相关使用人员 &#xff08;2&…

配天智造自主原创数字工厂:百余名员工人均创收122万

配天智造&#xff08;832223&#xff09;2022年度报告显示&#xff0c;报告期内公司实现营业收入1.3亿元&#xff0c;同比增长52%&#xff0c;归属于挂牌公司股东的净利润3867万元&#xff0c;同比增长28.11%。而这家公司全部在职员工仅有107人&#xff0c;人均创收约为122万。…

计算机科学导论笔记(七)

目录 九、程序设计语言 9.1 演化 9.1.1 机器语言 9.1.2 汇编语言 9.1.3 高级语言 9.2 翻译 9.2.1 编译 9.2.2 解释 9.2.3 翻译过程 9.3 编程模式 9.3.1 面向过程模式 9.3.2 面向对象模式 9.3.3 函数式模式 9.3.4 声明式模式 9.4 共同概念 九、程序设计语言 9.1 …

Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用

前言 本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识&#xff0c;具体内容包括分布式系统存在的问题&#xff0c;分布式系统问题的解决方案&#xff0c;Sentinel介绍&#xff0c;Sentinel快速开始&#xff08;包括&#xff1a;API实现Sentinel资源保护&#xff0c;…