定义:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

结构:(书中图,侵删)

一个申明克隆自己的接口
若干具体的需要克隆自己的类
 
这个结构很简单,而且在Java中那个接口是不需要自己写的。
Java类库中有现成的Cloneable接口,这只是一个标记接口,里面没有任何方法,但如果不加这个标记,会抛CloneNotSupportedException异常。
真正的clone()方法继承自Object类,但是必须要重写。
这里的clone()方法是浅克隆。

这里需要先解释一下深克隆和浅克隆的区别:
克隆,顾名思义,就是复制一个一模一样的。
java clone()方法的操作方式就是,开辟一块和当前对象一样的空间,然后把内容原样拷贝过去。
这导致的结果就是:
基础类型(char、int、long等)会是直接的值拷贝过去。
但是像对象这些拷贝过去的就只是引用,导致,所有克隆出来的孩子里的引用类型都指向同一个地方,而不是每人新建了一份。
这就是浅克隆。
深克隆就是把上述指向同一个地方的引用换成了每个人都指向一个新的地方,里面的值依旧是一样的。(下面的例子会使用深克隆)

实例:

一个歌手,他有基本信息:姓名、年龄;
热门歌曲信息:歌名、发行时间。
歌手类:
package designpattern.prototype;

public class Singer implements Cloneable {
String name;
int age;
HotMusic hotMusic; public Singer(String name, int age, HotMusic hotMusic) {
super();
this.name = name;
this.age = age;
this.hotMusic = hotMusic;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public HotMusic getHotMusic() {
return hotMusic;
} public void setHotMusic(HotMusic hotMusic) {
this.hotMusic = hotMusic;
} @Override
protected Object clone() throws CloneNotSupportedException {
Singer singerClone = (Singer) super.clone();
singerClone.hotMusic = (HotMusic) hotMusic.clone();// 这一句,下面解释
return singerClone;
} @Override
public String toString() {
return "Singer [name=" + name + ", age=" + age + ", hotMusic=" + hotMusic + "]";
} }
歌曲信息类:
package designpattern.prototype;

public class HotMusic implements Cloneable {
String name;
String date; public HotMusic(String name, String date) {
super();
this.name = name;
this.date = date;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getDate() {
return date;
} public void setDate(String date) {
this.date = date;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} @Override
public String toString() {
return "HotMusic [name=" + name + ", date=" + date + "]";
} }
客户端:

package designpattern.prototype;

public class Client {
public static void main(String[] args) {
Singer singer1 = new Singer("周杰伦", 40, new HotMusic("告白气球", "2016"));
System.out.println(singer1); try {
Singer singer2 = (Singer) singer1.clone();
singer2.hotMusic.setName("等你下课");
singer2.hotMusic.setDate("2018");
System.out.println("========================================================");
System.out.println(singer1);
System.out.println(singer2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} } }
输出结果:(深克隆)
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
========================================================
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]
如果把歌手类中注释的那一句去掉,结果会是:(浅克隆)
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=告白气球, date=2016]]
========================================================
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]
Singer [name=周杰伦, age=40, hotMusic=HotMusic [name=等你下课, date=2018]]

总结:

其实之前我从来都没有用过这个方法,之前看到文中说,要创建多个一模一样的对象,直接循环new不就得了?还搞那么麻烦。
看到书中的话对我有很大的启发,我就直接整理一下敲上来了:
每new一次,都要执行一次构造函数,如果构造函数的执行时间很长,那么多次执行会很低效。
一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象的创建细节,又对性能是大大的提高。
结合我上面说的,克隆是直接复制内存的,显然比执行构造方法高效的多。

设计模式 | 原型模式(prototype)的更多相关文章

  1. PHP设计模式 原型模式(Prototype)

    定义 和工厂模式类似,用来创建对象.但实现机制不同,原型模式是先创建一个对象,采用clone的方式进行新对象的创建. 场景 大对象的创建. 优点 1.可以在运行时刻增加和删除产品 2.可以改变值或结构 ...

  2. [工作中的设计模式]原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  3. C#设计模式——原型模式(Prototype Pattern)

    一.概述 在软件开发中,经常会碰上某些对象,其创建的过程比较复杂,而且随着需求的变化,其创建过程也会发生剧烈的变化,但他们的接口却能比较稳定.对这类对象的创建,我们应该遵循依赖倒置原则,即抽象不应该依 ...

  4. 设计模式-原型模式(Prototype)

    场景分析: 前面我们提到,交易对象Trade,还有继承他的债券交易BondTrade.期货交易FutureTrade. 现在有一个需求,需要提供方法将交易拆分成多笔小交易. 代码如下(如果没有clon ...

  5. 设计模式——原型模式(Prototype Pattern)

    原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象. UML 图: 原型类: package com.cnblog.clarck; /** * 原型类 * * @author c ...

  6. 大话设计模式--原型模式 Prototype -- C++实现

    1. 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象... 注意: 拷贝的时候是浅拷贝 还是 深拷贝, 来考虑是否需要重写拷贝构造函数. 关键在于: virtual Pro ...

  7. 设计模式——原型模式(Prototype)

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.——DP UML类图 模式说明 如果把在一张纸上手写一篇简历的过程看成是类的实例化过程,那么通过原型模式创建对象的过程就是拿着这张纸到复印 ...

  8. 设计模式--原型模式Prototype(创建型)

    一.原型模式 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.原型模式实现的关键就是实现Clone函数,还需要实现深拷贝. 二.UML类图 三.例子 //父类 class Resume ...

  9. 谈谈设计模式~原型模式(Prototype)

    返回目录 原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例(clone),而不是新建(new)实例.被复制的实例就是我们所称的“原型”,这个原型是可定制的. 原型模式 ...

  10. Net设计模式实例之原型模式( Prototype Pattern)

    一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...

随机推荐

  1. PAT1134:Vertex Cover

    1134. Vertex Cover (25) 时间限制 600 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A vertex ...

  2. redis两种持久化方法对比分析

    1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...

  3. Go调用C代码,Cgo札记

    http://www.myexception.cn/program/679738.html Go调用C代码,Cgo笔记 参考: 官方文档: http://golang.org/cmd/cgo/ htt ...

  4. 玩转PHP(一)---php中处理汉字字符串长度:strlen和mb_strlen

    注:本文为小编原创,如若转载,请注明出处:http://blog.csdn.net/u012116457/article/details/42536039 今天正式开始学习PHP了,不过小编一不小心就 ...

  5. canvas学习笔记(一)

    canvas是HTML5的新元素之一.使用canvas可以直接在HTML上进行图形操作,所以它具有极大的应用价值.canvas元素本身不具有绘图能力,它需要借助JavaScript来实现绘图功能. c ...

  6. Smokeping

    Smokeping允许你监测多台服务器. Smokeping使用RRDtool来存储数据,另外,其可基于RRDtool输出生成相应的统计图表. Smokeping由两个部分组成.一个运行在后台.定期收 ...

  7. IZT复杂电磁环境记录回放和模拟系统

    结合实验室复杂电磁环境特性与模拟研究需求,实现对复杂多变的电磁环境录制.分析.重构和模拟,记录回放系统应具备如下几项能力: 1.电磁环境信号记录能力:能够实现对9KHz-18GHz频带范围内射频信号的 ...

  8. golang使用Nsq

    为什么要使用Nsq 最近一直在寻找一个高性能,高可用的消息队列做内部服务之间的通讯.一开始想到用zeromq,但在查找资料的过程中,意外的发现了Nsq这个由golang开发的消息队列,毕竟是golan ...

  9. 用PCA(主成分分析法)进行信号滤波

    用PCA(主成分分析法)进行信号滤波 此文章从我之前的C博客上导入,代码什么的可以参考matlab官方帮助文档 现在网上大多是通过PCA对数据进行降维,其实PCA还有一个用处就是可以进行信号滤波.网上 ...

  10. 【爆料】-《卧龙岗大学毕业证书》UOW一模一样原件

    ☞西悉尼大学毕业证书[微/Q:865121257◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&a ...