创建型模式:原型模式

个人公众号原文:
创建型模式:原型模式

景

五大创建型模式之五:原型模式。

简介

姓名 :原型模式

英文名 :Prototype Pattern

价值观 :效率第一

个人介绍

Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
(来自《设计模式之禅》)

又到了一个系列的最后一篇文章了,今天是创建型模式的最后一篇。什么是创建型模式呢?创建型模式是对类的实例化过程进行抽象,使对象的创建和使用分离,从而使代码更加灵活。

我们平时使用最多的一种创建对象方式就是 new ABC(),直接通过构造方法来创建一个对象。通过原型模式来创建对象则不用调用构造方法,就可以创建一个对象。下面来揭开它的面纱。

你要的故事

前几天有出版社的老师邀请写书,鉴于深知自己水平还不足以出书,所以没有合作,还在努力学习,以后有能力有机会再考虑这方面的事情。

今天的故事就从出书讲起。我们知道一本新书发版的时候,会复印很多册,如果销售得好,会有很多个印刷版本。我们来了解复印一批书籍这个过程是怎么实现的。小明写下了下面这段代码。

public class NoPrototypeTest {public static void main(String[] args) {for (int i = 1; i <= 10; i ++) {Book book = new Book("娱乐至死", "尼尔波兹曼", "社会科学", "XXXX");System.out.println("复印书籍:" + book.getName() + ",第 " + i + " 本");}}}class Book {private String name;private String author;private String type;private String content;public Book(String name, String author, String type, String content) {this.name = name;this.author = author;this.type = type;this.content = content;System.out.println("实例化书籍:" + this.name);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}// 打印结果:
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 1 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 2 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 3 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 4 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 5 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 6 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 7 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 8 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 9 本
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 10 本

上面小明的代码复印了 10 本《娱乐至死》,代码逻辑没有问题,有个问题就是复印一本就实例化一次书籍,这个实例化可以减少么?使用原型模式可以实现。小明根据这些提示,重新修改了代码。

public class PrototypeTest {public static void main(String[] args) {Book2 book1 = new ConcreteBook("娱乐至死", "尼尔波兹曼", "社会科学", "XXXX");System.out.println("复印书籍:" + book1.getName() + ",第 " + 1 + " 本");for (int i = 2; i <= 10; i ++) {Book2 book2 = (Book2) book1.clone();System.out.println("复印书籍:" + book2.getName() + ",第 " + i + " 本");}}}/*** 抽象类*/
abstract class Book2 implements Cloneable {private String name;private String author;private String type;private String content;public Book2(String name, String author, String type, String content) {this.name = name;this.author = author;this.type = type;this.content = content;System.out.println("实例化书籍:" + this.name);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overrideprotected Object clone() {try {return super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}
}/*** 具体类*/
class ConcreteBook extends Book2 {public ConcreteBook(String name, String author, String type, String content) {super(name, author, type, content);}
}打印结果:
实例化书籍:娱乐至死
复印书籍:娱乐至死,第 1 本
复印书籍:娱乐至死,第 2 本
复印书籍:娱乐至死,第 3 本
复印书籍:娱乐至死,第 4 本
复印书籍:娱乐至死,第 5 本
复印书籍:娱乐至死,第 6 本
复印书籍:娱乐至死,第 7 本
复印书籍:娱乐至死,第 8 本
复印书籍:娱乐至死,第 9 本
复印书籍:娱乐至死,第 10 本

看,打印结果和第一次实现的结果完全不一样,这一次只实例化了一次,后面复印的书籍都没有实例化。我们看看代码的变化,代码中最最主要的就是 Book2 实现了 Cloneable 接口,这个接口有个 clone() 方法,通过实现这个方法,可以实现对象的拷贝,就是不用调用构造方法,直接通过对内存的拷贝来创建一个新的对象。这就是原型模式的实现方式,通过原型模式可以提高创建对象的效率

代码:
Prototype Pattern

总结

通过原型模式,绕过构造方法创建对象,利用内存直接拷贝对象,提高对象的创建性效率。在有大量的对象创建或者类初始化消耗多资源的场景下可以利用原型模式来优化。当然在实现的过程中,要注意浅拷贝与深拷贝的问题,防止写出 bug,文章主要介绍原型模式,就不详细说这个问题了,留给大家去扩展了解。

参考资料:《大话设计模式》、《Java设计模式》、《设计模式之禅》、《研磨设计模式》、《Head First 设计模式》

推荐阅读:
创建型模式:单例模式
创建型模式:工厂方法
创建型模式:抽象工厂
创建型模式:原型模式
公众号之设计模式系列文章

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

公众号

转载于:https://www.cnblogs.com/liebrother/p/10328436.html

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

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

相关文章

我的前端工具集(五)提示工具之模态窗提示

我的前端工具集&#xff08;五&#xff09;提示工具之模态窗提示 liuyuhang原创&#xff0c;未经允许禁止转载 目录 我的前端工具集 1、需求 很多页面操作都需要提示&#xff0c;比如操作成功&#xff0c;操作失败之类。 总不能没事就console.log或者alert吧。 所以一个操作提…

min-width:100%和max-width:100%的区别

1.width:100%和width:auto width:100%,设定对象的宽度占父元素的100%不论设定元素的margin值是多少,不包含margin&#xff1b; width:auto&#xff0c;根据设定对象的实际大小而自适应宽度&#xff0c;考虑设定元素的Margin值得大小&#xff0c;包含Margin 2.max-width:100%和m…

Java 8 Friday:可选将保留为Java中的一个选项

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 Java 8星期五 每个星期五&#xff0c;我们都会向您展示一些不错的教程风格的Java 8新功能&#…

java动态拼接请求_在JavaWeb项目中处理静态文件或动态链接拼接网站地址的最优处理方案...

在开发网站时候我们会遇到下面问题&#xff1f;- 在引用网页中引用js和css或者动态的Servlet的时候我们是写绝对路径还是相对路径&#xff1f;- 如果写相对路径吧&#xff0c;上线偶尔会报404&#xff0c;还要手动去拼接绝对路径- 如果写绝对路径吧&#xff0c;你在本地写的时候…

新增数据库栏位脚本

IF NOT EXISTS(SELECT * FROM SYSCOLUMNSWHERE IDOBJECT_ID(NMNDIndicator) AND NAMENcheckperiod)BEGINALTER TABLE MNDIndicator ADD checkperiod NVARCHAR(100) NULL default END 转载于:https://www.cnblogs.com/snowball/archive/2007/05/14/745213.html

七天开发记录(3)

今天在网上找到了一个开发记账本微信小程序的网址 我看了一下这个APP的源代码&#xff0c;其用分为两个大包。 转载于:https://www.cnblogs.com/zjl-0217/p/10428525.html

做个商城吧(〇)

做个商城吧&#xff08;〇&#xff09; liuyuhang原创&#xff0c;未经允许进制转载&#xff01; 作为自己想写的一个系列&#xff0c;应该仔细认真的更下来 目录在文末 1、想法 自己一个人做个商城&#xff0c;这种想法一直萦绕着。 但是也有不同的声音&#xff1a; 有淘宝&am…

链表!比数组更适合做增删操作的数据结构

什么是链表&#xff1f; 链表和数组的对比&#xff1a;在大多数语言中&#xff0c;数组的大小是固定的&#xff0c;从数组的起点或中间添加或删除元素的成本很高&#xff0c;因为需要移动元素。链表中的每一个元素在内存中不是连续放置的&#xff0c;和它左右两侧元素是没有关系…

Java 8中的Base64 –加入乐趣为时不晚

最后&#xff0c;Java 8发布了。 最后&#xff0c;有一种执行Base64编码的标准方法。 长期以来&#xff0c;我们一直依赖于Apache Commons Codec&#xff08;无论如何还是很棒的&#xff09;。 内存敏感的编码人员将拼命使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder&am…

多层架构模型中的BLL 与 Model的解释

理想状态这两个可以合并到一起来&#xff0c;就是业务对象&#xff0c;但model是把这个业务对象中的数据提取了出来&#xff0c;作为一个数据载体&#xff0c;可以在层间传递。业务对象中除去这些数据剩下的方法就构成了BLL层。显示层Presentation Layer业务逻辑层Business Log…

java创建方法并引用_java – 创建非捕获方法引用,它将调用超类方法

我正在尝试重构以下代码&#xff1a;class Base {private Object a, b, <...>; // theres like 10 of these attributes of different typepublic Object a() {return a;}public Object b() {return b;}// more getters like the ones above}class RootNode extends Base…

maven快速入门

一。前提条件 你的电脑必须安装maven和java 二。检验安装 执行命令&#xff1a;mvn --version 输出&#xff1a; Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T20:41:4702:00) Maven home: D:\apache-maven-3.6.0\bin\.. Java version: 1.8.0_16…

如何使用JSR107缓存注释

最近&#xff0c;我对JSR107缓存注释以及JSR107的实现是否提供它们有一些疑问。 可以将缓存注释添加到Java类中&#xff0c;并将其作为方法调用缓存操作。 例如&#xff0c;下面是带注释的BlogManager。 CacheDefaults(cacheName "blgMngr") public class BlogMan…

js之作用域

1.什么是作用域 作用域是用于收集存储维护变量&#xff0c;以及当前执行代码声明的变量所拥有的权限&#xff0c; 例如 &#xff1a; function foo(a){ console.log(a); -------- 1 }; foo(666); console.log(a); ------- 2 此时执行该段代码 1 -- 处打印我们得…

TMS320F28335——IO控制/定时计操作

一、实现GPIO控制 1.硬件连接 从电路原理图上看来&#xff0c;LED灯是接在GPIO34 上的。 2.IO设置 2.1设置功能 GPXMUX1/2&#xff1a;功能选择寄存器   GPXMUX1/2 每组 IO 一般有 32 个 IO 口可以配置。GPXMUX1 对应每组的低 16 个 IO 口&#xff0c;GPXMUX2 对应高 16 个…

网页弹出窗口代码【来源于网络】

网页弹出窗口代码 1、最基本的弹出窗口代码 其实代码非常简单&#xff1a; < SCRIPT LANGUAGE"java script"> < !-- window.open ("page.html") --> < /SCRIPT> 因为这是一段java script代码&#xff0c;所以它们应该放在< SCRIPT L…

比Python、Java更快的 Go 语言,能否称霸江湖?

关注之后加星标&#xff0c;江湖要事早知道 ​ 文章来源&#xff1a;jb51.net 有一种语言堪称比语言排行榜前五热门选手的Python、Java更快&#xff0c;它就是GO语言。 Go于2009年11月正式宣布推出&#xff0c;成为开放源代码项目&#xff0c;并在Linux及Mac OS X平台上进行了实…

嗨,您好 。 。 ! 您如何评价Java / Java EE技能?

要知道&#xff0c;就是要知道你一无所知。 那就是真正知识的含义。 苏格拉底 这篇文章旨在为读者提供Java生态系统及其技术堆栈的快速概述。 老实说&#xff0c;从Java EE 7&#xff0c;Java SE 8到Java Embedded 8…&#xff0c;Java平台进行了许多革命性的更改和添加。 哇…

simulinkveristandlabview联合仿真——模型导入搭建人机界面

目录 1.软件版本 2.搭建simulink仿真模型 编译错误 3.导入veristand并建立工程 4.veristand导入labview labview显示veristand工程数据 labview设置veristand工程数据 运行labview工程 1.软件版本 matlab2020a&#xff0c;veristand2020 R4&#xff0c;labview2020 SP…

jquery appendTo用法

$("#top_cartWarp").appendTo($("#top_main_right")).css(position,relative).css(top,0px); 返回值:jQueryappendTo(content) V1.0概述 把所有匹配的元素追加到另一个指定的元素元素集合中。 实际上&#xff0c;使用这个方法是颠倒了常规的$(A).append(B)…