前面的文章介绍了工厂模式和抽象工厂模式、建造者模式,它们都属于创建型设计模式,今天介绍另外一种创建性设计模式,原型模式(prototype pattern)。

什么时候用原型模式?

我个人一直有种观点,就是骨子里懒惰的程序员都喜欢用设计模式,因为懒所以得想尽办法让自己更高效。

原型模式就是一种懒操作,用于频繁创建对象的场所。

日常生活中,我们都说两个人很像,简直就是一个模子里引出来的。

那么,代码中原型模式就是这样基于一个对象快速复制另外一个对象,而无需重头全新创建。

比如,代码要产生 7 个葫芦娃,怎么用原型模式做呢?

葫芦娃长这样:

每个葫芦娃长得都差不多,可能就名字不同,衣服颜色不同。

我们可以定义一个葫芦娃类,然后先创建第一个,然后通过原型模式快速复制更多个。

原型模式实现

非常简单,先定义一个 Cloneable 接口,然后定义一个实现类 CalabashBrother。

因为 Java 语言就支持 clone 操作,所以很容易写出原型设计模式代码。

Java 例子


public class CalabashBrother implements  Cloneable{String name;String color;public CalabashBrother(String name,String color){System.out.println("---Construct obj---");this.name = name;this.color = color;}@Overridepublic String toString(){return "ID:"+hashCode()+" My name is "+this.name+" my skin is " + this.color;}@Overrideprotected Object clone(){CalabashBrother brother = null;try {brother = (CalabashBrother) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return brother;}
}

定义了 CalabashBrother 代表葫芦娃。

复写了 Clone 方法。

另外复写了 toString() 方法,方便调试时查看对象信息,这里用 hashcode 指示不同的对象。

然后可以写 Demo 测试了。

public class PrototypeDemo {public static void main(String[] args) {String colorlist[] = {"red","green","yellow","crown","pink","blue","purple"};CalabashBrother brother1 = new CalabashBrother("brother1",colorlist[0]);System.out.println(brother1);for (int i = 1;i < 7;i++) {CalabashBrother brother = (CalabashBrother)brother1.clone();brother.name = "brother"+(i+1);brother.color = colorlist[i];System.out.println(brother);}}
}

运行程序,结果如下:

---Construct obj---
ID:2129789493 My name is brother1 my skin is red
ID:668386784 My name is brother2 my skin is green
ID:1329552164 My name is brother3 my skin is yellow
ID:363771819 My name is brother4 my skin is crown
ID:2065951873 My name is brother5 my skin is pink
ID:1791741888 My name is brother6 my skin is blue
ID:1595428806 My name is brother7 my skin is purple

大家仔细观看输出可以发现 2 个特征:

  1. 只调用了一次构造函数,后面通过 clone() 的对象没有再调用类的构造函数。
  2. clone 出来的对象 ID 不一样,这样保证了是新的的对象。

浅拷贝和深拷贝

讲原型模式的时候离不开这个话题。

浅拷贝的时候只考虑值传递,如果一个类中有引用其它对象,那么只会复制对象的引用。

深拷贝除了值传递外,引用的内容同样也会复制。

public class CalabashBrother implements  Cloneable{String name;String color;Calabash calabash = new Calabash();public CalabashBrother(String name,String color){System.out.println("---Construct obj---");this.name = name;this.color = color;}
}假设 CalabashBrother 中有个对象是 calabash,如果直接调用 super.clone() 假设 clone 出来的对象是 obj,那么 obj.calabash 其实和原型对象是同一份内容。这就是**浅拷贝**。如果要实现**深拷贝**也很简单,只用一个个对象手动调用 clone() 就好了。```java
@Override
protected Object clone(){CalabashBrother brother = null;try {brother = (CalabashBrother) super.clone();brother.calabash = (Calabash) calabash.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return brother;
}

Android 源码中的原型模式

Android 源码中的原型模式多不胜数,这里摘抄一段。


package android.animation;public abstract class Keyframe implements Cloneable {boolean mHasValue;private TimeInterpolator mInterpolator = null;@Overridepublic abstract Keyframe clone();/*** This internal subclass is used for all types which are not int or float.*/static class ObjectKeyframe extends Keyframe {Object mValue;ObjectKeyframe(float fraction, Object value) {mFraction = fraction;mValue = value;mHasValue = (value != null);mValueType = mHasValue ? value.getClass() : Object.class;}@Overridepublic ObjectKeyframe clone() {ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), hasValue() ? mValue : null);kfClone.mValueWasSetOnStart = mValueWasSetOnStart;kfClone.setInterpolator(getInterpolator());return kfClone;}}}

Keyframe 是 Android 动画中的关键帧,我们都知道动画是连续的一帧帧图片指定时间播放形成的视觉效果,Android 中的 SDK 有很方便的动画定义 API,一段动画中有许多关键帧,关键帧之间通过数学插值的方法自动生成其它帧,因为类型一样,所以关键帧可以通过原型模式来实现。

总结

原型模式非常有用,对于需要频繁创建对象的场景,用原型模式再合适不过了,关键原因在于拷贝时是直接从内存中获取而不是重新再执行一次构造函数。

实际上,不单单是 Java 语言会用到这个模式,其它开发语言只要是频繁创建同类型不同对象都可以用到,比如,我做 OpenCV 的时候,处理视频流的时候就经常要对 mat 进行原型拷贝。

设计模式(五):利用原型模式复制几个葫芦娃相关推荐

  1. 设计模式五:原型模式

    目录 原型模式 浅克隆 深克隆 原型模式 原型模式是指:原型实例指定原型对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式的适用场景: 1.类初始化消耗资源较多 2.new产生一个对象需要非常繁 ...

  2. 设计模式(五)—— 原型模式(定义、案例分析、特点、缺点)

    文章目录 前言 正文 一.定义 二.模式结构及分析 (一) 模式结构 (二) 模式分析 三.情景假设 四.情景分析 (一) 浅克隆 (二) 深克隆 五.模式优点.缺点 (一)模式优点 (二)模式缺点 ...

  3. 设计模式笔记五:原型模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出 菜鸟教程讲的比较难懂,有篇简洁易懂的博客: http://blog.csdn.net/j ...

  4. Java描述设计模式(05):原型模式

    一.原型模式简介 1.基础概念 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. 2.模式结构 原型模式要求对象实现一个 ...

  5. 23种设计模式[5]:原型模式

    定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备 ...

  6. 设计模式快速学习(五)原型模式

    用于创建重复的对象,同时又能保证性能.通俗的讲,原型模式就是克隆对象,直接copy字节码,不走构造方法,性能非常高.ORM中经常用到. 注意 只支持9种数据类型的深拷贝: 8大基本类型(int lon ...

  7. 设计模式学习笔记-原型模式

    一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象: 二.模式中的角色 Prototype:声明一个克隆自身的接口: ConcretePrototype:实现一个克隆自身的操作: ...

  8. 设计模式 之美 -- 原型模式

    文章目录 1. 解决问题 2. 应用场景 3. 实现方式 C++实现 C语言实现 4. 缺点 5. 和其他三种创建模式的对比(单例,工厂,建造者) 1. 解决问题 如果对象的创建成本较大,而同一个类的 ...

  9. 【设计模式 06】原型模式(克隆??)

    原型模式(clone?) Prototype pattern refers to creating duplicate object while keeping performance in mind ...

  10. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

最新文章

  1. 第三届全国大学生智能汽车竞赛获奖名单
  2. 人类一败涂地电脑版_【游戏资讯】这是PC版塞尔达?终极无敌暴力缝合怪登陆Steam!PS3模拟器更新后可流畅运行美末!...
  3. cesium 设置时间_Cesium应用篇:3控件(1)Clock
  4. 手机常用分页加载loading框
  5. android 悬浮球简书,轻松自制flyme悬浮球
  6. 子模板继承父模板示例_模板设计模式示例
  7. 经典php代码,HTML_php教程:经典PHP代码,经典循环例子 HTMLHEAD - phpStudy
  8. 小红书成立六周年内部信:月活用户量已经突破8500万
  9. 实录 | 旷视研究院详解COCO2017人体姿态估计冠军论文(PPT+视频)
  10. .net 编译、反编译、查壳、脱壳、反混淆工具
  11. 为系统安装盘集成Server Pack补丁包
  12. java批处理框架 pdf_史上最轻松入门之Spring Batch - 轻量级批处理框架实践
  13. 51单片机波特率计算c语言,51单片机波特率怎么算?51单片机波特率计算公式
  14. 行人仿真操作教程(一)行人仿真是什么?哪个软件好用?
  15. 「IT基础」计算机网络结构
  16. Tera Term 工具的使用
  17. linux网卡驱动如何安装,linux下网卡驱动安装全过程
  18. 计算机模拟量与数字量的转换,PLC开关量与模拟量编程数值转换原理
  19. Linux内核学习--ARM系列处理器(指令集等)性能全面分析
  20. MHP3内存修改辅助工具

热门文章

  1. 强化学习实战(九) Linux下配置星际争霸Ⅱ环境
  2. [转]WinRAR破解方法
  3. 山东理工ACM 1445 素数
  4. gulp-tinypng-nokey [error]: xxx Too many files uploaded at once
  5. 微信支付-此商家的收款功能已被限制,暂无法支付(解决方案)
  6. 数据分析需要学习的技能有哪些?
  7. neo4j学习总结--第三课 Cypher(CQL)命令一
  8. volatility用法
  9. join and list删除 and set集合 and 深浅拷贝
  10. 大一新生计算机掌握情况word,2021年大一计算机学习心得word版