设计模式之原型模式【创造者模式】

news2024/11/18 13:45:07

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…

文章目录

  • 前言
  • 一、概述
  • 二、结构
  • 三、实现
  • 四、案例
  • 五、使用场景
  • 六、扩展(深克隆)
  • 总结


前言

一、概述
二、结构
三、实现
四、案例
五、使用场景
六、扩展(深克隆)


一、概述

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

二、结构

原型模式包含如下角色:

  • 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

接口类图如下:
在这里插入图片描述

三、实现

原型模式的克隆分为浅克隆和深克隆。

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

Java中的Object类中提供了 clone() 方法来实现浅克隆。 Cloneable 接口是上面的类图中的抽象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。代码如下:

Realizetype(具体的原型类):

public class Realizetype implements Cloneable {

    public Realizetype() {
        System.out.println("具体的原型对象创建完成!");
    }

    @Override
    protected Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型复制成功!");
        return (Realizetype) super.clone();
    }
}

Client (测试访问类):

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原型类对象
        Realizetype r1 = new Realizetype();
        //调用Realizetype类中的clone方法进行对象的克隆
        Realizetype r2 = r1.clone();

        System.out.println("对象r1和r2是同一个对象?" + (r1 == r2));
    }
}

在这里插入图片描述

四、案例

用原型模式生成“三好学生”奖状

同一学校的“三好学生”奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个“三好学生”奖状出来,然后在修改奖状上的名字即可。

类图如下:
在这里插入图片描述
代码如下:

//奖状类
public class Citation implements Cloneable {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return (this.name);
    }

    public void show() {
        System.out.println(name + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }
}

//测试访问类
public class CitationTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation c1 = new Citation();
        c1.setName("张三");

        //复制奖状
        Citation c2 = c1.clone();
        //将奖状的名字修改李四
        c2.setName("李四");

        c1.show();
        c2.show();
    }
}

五、使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象。
  • 性能和安全要求比较高。

六、扩展(深克隆)

将上面的“三好学生”奖状的案例中Citation类的name属性修改为Student类型的属性。代码如下:

//奖状类
public class Citation implements Cloneable{

//    //三好学生上的姓名
//    private String name;
//
//    public String getName() {
//        return name;
//    }
//
//    public void setName(String name) {
//        this.name = name;
//    }
    private Student stu;

    public Student getStu() {
        return stu;
    }

    public void setStu(Student stu) {
        this.stu = stu;
    }

    public void show() {
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }

    @Override
    public Citation clone() throws CloneNotSupportedException{
        return (Citation) super.clone();
    }

}

//学生类
public class Student {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

//测试类
public class CitationTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        //1、创建原型对象
        Citation c1 = new Citation();
        Student stu=new Student();
        stu.setName("张三");
        c1.setStu(stu);
//        c1.setName("张三");

        //复制奖状对象
        Citation c2 = c1.clone();
        Student stu1=c2.getStu();
        stu1.setName("李四");
        //将奖状的名字修改李四
//        c2.setName("李四");

        c1.show();
        c2.show();
    }
}

在这里插入图片描述

此时之所以名字会相同是因为Citation类此时复制的是Student类【引用类型】,引用类型是同一个地址,而原本的Citation类中是String类型【基础类型】,并不是同一块地址。

运行结果为:
在这里插入图片描述
说明:

​ stu对象和stu1对象是同一个对象,就会产生将stu1对象中name属性值改为“李四”,两个Citation(奖状)对象中显示的都是李四。这就是浅克隆的效果,对具体原型类(Citation)中的引用类型的属性进行引用的复制。这种情况需要使用深克隆,而进行深克隆需要使用对象流。代码如下:

public class CitationTest {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        //1、创建原型对象
        Citation c1 = new Citation();
        Student stu=new Student();
        stu.setName("张三");
        c1.setStu(stu);

        //创建对象输出流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Lenovo\\Desktop\\b.txt"));
        //将c1对象写出到文件中
        oos.writeObject(c1);
        oos.close();

        //创建对象出入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Lenovo\\Desktop\\b.txt"));
        //读取对象
        Citation c2 = (Citation) ois.readObject();
        //释放资源
        ois.close();
        //获取c2奖状所属学生对象
        Student stu1 = c2.getStu();
        stu1.setName("李四");

        //判断stu对象和stu1对象是否是同一个对象
        System.out.println("stu和stu1是同一个对象?" + (stu == stu1));

        c1.show();
        c2.show();

    }
}

在这里插入图片描述

运行结果为:
在这里插入图片描述

注意:Citation类和Student类必须实现Serializable接口,否则会抛NotSerializableException异常。


总结

以上就是设计模式之原型模式【创造者模式】的相关知识点,希望对你有所帮助。
积跬步以至千里,积怠惰以至深渊。时代在这跟着你一起努力哦!

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

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

相关文章

数据库云平台新数科技完成B轮融资,打造全链路智能化数据库云平台

数据库云平台软件厂商「北京新数科技有限公司」(以下简称「新数科技」)已于2023年完成B1轮和B2轮融资,分别由渤海创富和彬复资本投资;义柏资本担任本轮融资独家财务顾问。 新数科技成立于2014年,当前产品矩阵包括数据库…

120基于matlab的LMS自适应滤波算法

基于matlab的LMS自适应滤波算法,如、解相关LMS算法,滤波型LMS算法,变换域LMS算法,输出滤波前后及学习曲线图。数据可更换自己的,程序已调通,可直接运行。 120自适应滤波算法变换域LMS算法 (xiaohongshu.com…

解决Android AAPT: error: resource android:attr/lStar not found. 问题

错误信息 /xxx/gjc/.gradle/caches/transforms-2/files-2.1/930c42acd29d295ce5bc495c3b84423e/core-1.9.0/res/values/values.xml:104:5-113:25: AAPT: error: resource android:attr/lStar not found. not found 资源位置 场景 原Android studio中的项目都是在git上面拉的老项…

cad基础知识1

cad: 点移动会变成线,线移动会变成面,面移动会变成一个实体 f7: 取消cad里的网格 f12: 动态输入 dim:更加智能的标准两端点的距离。 f8:如果按了f8,上下左右都是一条直线,不会变歪。 f9: 开启捕捉模式。 …

实验笔记之——基于windows复现Instant-NGP

之前博客对NeRF-SLAM进行了调研,本博文先复现一下Intant-NGP。 学习笔记之——NeRF SLAM(基于神经辐射场的SLAM)-CSDN博客文章浏览阅读851次,点赞22次,收藏21次。NeRF 所做的任务是 Novel View Synthesis(…

以爱之名,与“EYE”同行 蔡司光学公益行一直在路上

用心传递公益温暖之力,助力更多乡村学童拥有光明未来。2023年12月26日,一场以“EYE”为主题的公益活动正在中卫市宣和镇东台小学举办。本次,眼视光领域领军品牌蔡司光学携手中卫德明眼科的专业视光团队一同来到活动现场,为该校全体…

文件重命名技巧:找到最简单的办法,删除文件名中的下划线

在日常工作中,经常要处理大量的文件,包括重命名文件。有时候可能会遇到文件名中包含下划线的情况,这使得文件名变得复杂且不易读。要简化文件名并使其更易于管理,可以使用一些简单的技巧来删除文件名中的下划线。现在一起来看云炫…

山西电力市场日前价格预测【2024-01-04】

日前价格预测 预测说明: 如上图所示,预测明日(2024-01-04)山西电力市场全天平均日前电价为197.93元/MWh。其中,最高日前电价为376.04元/MWh,预计出现在18:15。最低日前电价为0.00元/MWh,预计出…

案例分享:Qt多国语言输入法软键盘

若该文为原创文章,转载请注明出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/135346374 红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

AIGC年度回顾!2024向量数据库是否还是AI发展方向之一?

引言 2023 年,是 AI 技术大爆发的一年,从年初到年末,全球关心技术发展的人们见证了一次次的 AI 技术升级,也逐步加深着对 AGI 发展的畅想。而伴随着生成式人工智能的飞速发展,向量数据库以其独特的技术优势逐渐崭露头角…

第一个Qt程序----Hello word!

从今天起就开始我们的第一个Qt小程序,点击New Project后点击右侧的Application后点击Qt Widgets Application。Qt Widgets 模块提供了一组UI元素用于创建经典的桌面风格的用户界面,Widgets是小部件的意思,也可以称为控件,因此Qt …

OpenHarmony之HDF驱动框架

概述 HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在…

LeetCode每日一题.06(翻转二叉树)

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1] 示例 2: 输入:root [2,1,3] 输出:[2,3,1] 示例 3&…

golang学习专栏

GOLANG专栏 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教程 MySQ…

Go中interface != nil不一定不是nil

摘要: interface{} 值 ! nil不一定不是nil,应使用reflect库判断是否是nil。 测试示例: // todo interface ! nil 不一定 不是nil var value map[string]interface{} reqMap : make(map[string]interface{}) reqMap["key"] valu…

Python项目15:教你使用pillow把女神的图片,添加表白文字。

★★★★★博文创作不易,我的博文不需要打赏,也不需要知识付费,可以白嫖学习编程小技巧。使用代码的过程中,如有疑问的地方,欢迎大家指正留言交流。喜欢的老铁可以多多点赞收藏分享置顶,小红牛在此表示感谢…

洁净间级别确认和环境监测相关法规指南汇总

一 洁净级别确认 1. 用于生产无菌药品的洁净室和洁净空气设备如单向流系统(UDAF)、限制进入屏障系统(RABS)和隔离器,应根据所需环境特性进行确认。生产操作需要在适当洁净度级别的环境中进行,以降低粒子或…

格局初现:京东阿里都瞄准了这个万亿级的大市场

核 心 要 点 ▪ 企业采购有哪些痛点和解决方案?行业的关键赛点是什么? ▪ 现行格局是何情况?代表性玩家各自有何特点? ▪ 未来企业采购将往何处去? 当这样一组数据摆在眼前的时候,你或许会感到难以置…

CMake入门教程【核心篇】编译类型Debug、Release、MinSizeRel、RelWithDebInfo

文章目录 1.说明1.1 Debug 配置1.2 Release 配置1.3 MinSizeRel 配置1.4 RelWithDebInfo 配置 2.提供的编译类型3.示例结论 1.说明 CMake作为一款强大的构建系统,提供了多种编译配置选项。这些配置影响编译过程中的优化级别和调试信息的包含情况。以下是CMake提供的…

C#中字母与ASCⅡ码的转换

目录 一、关于ASCⅡ及与字符互转 1.主要用到Encoding对象的GetBytes方法 2.Char显式转换为数值类型得到ASCⅡ 二、实例 三、生成效果 四、程序中的一些知识点 1.IsLetterOrDigit() 2.GetBytes() 3.TryParse(string, out int) 一、关于ASCⅡ及与字符互转 ASCⅡ(Americ…