设计模式篇---原型模式

news2025/1/31 20:42:11

文章目录

    • 概念
    • Java中的克隆方法
    • 实例
    • 使用场景

概念

定义:使用原型实例指定待创建对象的类型,并通过复制这个原型来创建新的对象。
原型模式主要有以下几部分组成:
Prototype(抽象原型类):具体原型类的接口或者抽象类。
ConcretePrototype(具体原型类):它实现抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。
Client(客户类):在客户端可以创建原型对象,然后通过克隆创建新的对象。
原型模式的类图如下:
在这里插入图片描述

Java中的克隆方法

在java中,所有的类均继承了Object类,里面有一个clone()方法,可以将一个java对象复制一份,因此我们可以使用这个方法进行浅克隆。但需要实现Cloneable接口,它只是一个声明式的接口,里面没有任何函数,但是如果使用clone方法的时候不实现该接口,会抛出异常:
在这里插入图片描述
浅克隆:如果原型对象中的成员变量是值类型,则复制的时候都会复制一份给新的克隆对象,但是如果成员变量是引用类型(如类、接口、数组等),则只是将引用类型对象的地址引用复制一份给新的克隆对象,也就是新的克隆对象和之前原型对象中引用类型的成员变量是同一份地址。

深克隆:深克隆是将原型对象的所有成员变量(包括引用类型)都复制一份给新的克隆对象。

实例

在工作中,我们会写周报,但有些时候周报中的附件是重复的,这个场景下,我们可以使用原型模式来提高周报的创建效率。

在这里插入图片描述

浅克隆的实现
附件类

@Data
public class Attachment {
    private String name;

    public void download(){
        System.out.println("下载附件,文件名为" + name);
    }
}

周报类

@Data
public class WeeklyLog implements Cloneable {
    private Attachment attachment;
    private String name;
    private String date;
    private String content;

    public WeeklyLog clone() {
        Object obj = null;
        try {
            //浅克隆
            obj = super.clone();
            return (WeeklyLog) obj;
        } catch (CloneNotSupportedException e) {
            System.out.println("不支持复制");
            return null;
        }
    }
}

客户端

public class Client {

    public static void main(String[] args) {
    WeeklyLog log_previous, log_new;
    log_previous = new WeeklyLog(); //创建原型对象
    Attachment attachment = new Attachment(); //创建附件对象
    log_previous.setAttachment(attachment); //将附件添加到周报中
    log_new = log_previous.clone(); //调用克隆方法创建克隆对象
    //比较周报
    System.out.println("周报是否相同? " + (log_previous == log_new));
    //比较附件
    System.out.println("附件是否相同? " + (log_previous.getAttachment() == log_new.getAttachment()));
    }
}

打印结果:
在这里插入图片描述

深克隆实现
深克隆只需要将附件类也实现Cloneable接口即可,WeeklyLog中的clone方法改写如下:

@Data
public class WeeklyLog implements Cloneable {
    private Attachment attachment;
    private String name;
    private String date;
    private String content;

    public WeeklyLog clone() {
        WeeklyLog obj = null;
        try {
            this.attachment.clone();
            //深复制,让附件也克隆一份
            obj = (WeeklyLog) super.clone();
            obj.setAttachment(this.attachment.clone());
            return obj;
        } catch (CloneNotSupportedException e) {
            System.out.println("不支持复制");
            return null;
        }
    }
}

附件类

@Data
public class Attachment implements Cloneable {
    private String name;

    public void download(){
        System.out.println("下载附件,文件名为" + name);
    }

    public Attachment clone(){
        Object obj = null;
        try {
            obj = super.clone();
            return (Attachment)obj;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

打印结果
在这里插入图片描述

使用场景

1、创建新对象的成本较大时,可以通过clone方法减少开销。
2、系统要保存对象状态,但对象状态变化很小。
3、不需要使用工厂类来创建指定的对象,且类的实例对象中有较少的组合变量,通过复制原型对象的实例比使用构造方法更方便。

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

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

相关文章

Mybatis 全系列目录引导(持续更新)

基础篇 001Mybatis常用的网站及工具_存在,及合理的博客-CSDN博客GITHUB。https://blog.csdn.net/qq_26594041/article/details/131098123002Mybatis初始化引入_存在,及合理的博客-CSDN博客自动检测工程中的DataSource创建并注册SqlSessionFactory实例创建并注册SqlSessionTemp…

OpenGL光照之颜色

文章目录 创建一个光照场景 现实世界中有无数种颜色,每一个物体都有它们自己的颜色。我们需要使用(有限的)数值来模拟真实世界中(无限)的颜色,所以并不是所有现实世界中的颜色都可以用数值来表示的。然而我…

物联网Lora模块从入门到精通(四)对某些端口的初始化

一、前言 由于程序设计开发具有的不确定性,我们常常需要初始化某些特定的引脚,并读取引脚电平状态或向引脚输出高低电平。 二、代码实现 快速找到端口的初始化语句: 首先,找到board.c文件,在下图的位置,我…

【算法系列专栏介绍】

序言 你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记一级论点蓝色:用来标记二级论点 决定开一个算法专栏,希望能帮助大…

什么是域控服务器?域控服务器功能?部署域控需要考虑因素?域控组策略功能?

一、什么是域控制服务器? 域控制器(Domain Controller)是在Windows Server操作系统上运行的一个服务角色,它用于管理和控制一个或多个计算机的安全策略、用户身份验证和授权等任务。域控制器通常是用于企业网络中的主要身份验证和…

性能测试从0到1实战,超详细性能测试计划编写汇总...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、测试背景 首先…

yt-dlp 使用教程

参考:yt-dlp 使用教程 下载yt-dlp.exe,地址:Releases yt-dlp/yt-dlp GitHub windows下载.exe版本,放到指定路径下,我的是C:\Users\bellychang\Downloads 查看视频所有分辨率 yt-dlp.exe --proxy socks5://127.0.0.…

github action 基于个人项目实践

前言: DevOps 和 Jenkins 作为一名开发,虽然也没有经常听到 Devops (研发和运维一体化)这个概念,但日常工作中已经无处不在地用着 DevOps 工具。自研也好,基于开源项目改造也好,互联网公司基本都会有自已的…

强化学习Q-learning实践

1. 引言 前篇文章介绍了强化学习系统红的基本概念和重要组成部分,并解释了Q-learning算法相关的理论知识。本文的目标是在Python3中实现该算法,并将其应用于实际的实验中。 闲话少说,我们直接开始吧! 2. Taxi-v3 Env 为了使本文…

一文讲完Java常用设计模式(23种)

介绍 设计模式的起源可以追溯到20世纪80年代,当时面向对象编程开始流行。在这个时期,一些软件开发者开始注意到他们在不同的项目中遇到了相同的问题,并且他们开始寻找可重用的解决方案。这些解决方案被称为设计模式。最早提出设计模式的人是…

centos7的docker安装与简单介绍

docker的基本组成(三要素) 镜像容器仓库 理解:镜像可以理解成一个类,容器就是用这个类new出来的对象,仓库就是放镜像文件的。docker本身是容器运行载体或管理引擎 安装 安装gcc yum -y install gcc安装需要的软件…

Vcpkg介绍及使用

Vcpkg用于在Windows、Linux、Mac上管理C和C库,极大简化了第三方库的安装,它由微软开源,源码地址:https://github.com/Microsoft/vcpkg,最新发布版本为2023.04.15 Release,它的license为MIT。 在windows上安…

[解决方案]springboot怎么接受encode后的参数(参数通过=拼接)

springboot怎么接受encode后的参数(拼接& springboot怎么接受encode后的参数(拼接&)问题出现原因发送encode后的值在postman里面的情况这个时候该如何接受呢(encode后的值接受)controller层的代码用到的工具类CRequest springboot怎么接受encode…

软考A计划-系统架构师-官方考试指定教程-(14/15)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

数组删除元素使用remove最优的方法

Array.prototype.remove function(from, to) { var rest this.slice((to || from) 1 || this.length); this.length from < 0 ? this.length from : from; return this.push.apply(this, rest); };

Anaconda安装及入门教程(Windows、Ubuntu)

文章目录 安装Anaconda3UbuntuWindows 使用换源设置不自动启用conda环境显示环境创建环境激活环境查找某个包的版本安装某个版本的包 虚拟环境中安装包删除虚拟环境删除特定的包复制环境设置代理UbuntuWindows 使用 conda-pack 离线导入、导出环境安装conda-pack导出导入 安装A…

简单使用nacos、openFeign和Sentinel(建议看源码和截图一起看)

1、Nacos 1、下载nacos&#xff0c;可以从结尾获取压缩包和源码 2、下方图例是两个服务程序注册成功到注册中心&#xff0c;并且配置从配置中心拉取&#xff0c;成功访问数据库 3、nacos中配置项里的内容 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driv…

在linux上做移动开发必须知道这五个

导读随着越来越多的人依靠手机进行各种业务&#xff0c;移动应用开发的重要性也在不断增加。虽然他们与桌面应用程序有很多相似之处&#xff0c;但移动应用程序本身也具有一系列挑战和特殊性。因此&#xff0c;希望在当前市场找到有利就业的程序员将需要利用和发展当前需求的技…

第五章 结构化设计

结构化设计的概念 1. 设计的定义 一种软件开发活动&#xff0c;定义实现需求规约所需的软件结构。 结构化设计分为&#xff1a; (1)总体设计&#xff1a;确定系统的整体模块结构&#xff0c;即系统实现所需要的软件模块以及这些模块之间的调用关系。 (2)详细设计&#xff1a;…

从Referer到XMLHttpRequest:探究Web安全中的重要知识点

目录 Referer 概念 Referrer-policy&#xff08;可以一定程度上防御CSRF攻击&#xff09; 同源 iframe sandbox(沙箱): cookie的原理&#xff1a; 如何设置Referrer&#xff1f; 盗链 盗链的工作原理 三种情况下可以引用图片&#xff1a; XMLHTTPRequest AJAX&…