⑤ 设计模式的艺术-05.原型(Prototype)模式
场景
思考一下:克隆技术是怎么样的过程? 克隆羊多利大家还记得吗?
javascript语言中的,继承怎么实现?那里面也有prototype,大家还记得吗?
原型模式
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
就是java中的克隆技术,以某个对象为原型,复制出新的对象。显然,新的对象具备原型对象的特点
优势有:效率高(直接克隆,避免了重新执行构造过程步骤) 。
克隆类似于new,但是不同于new。new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出的新对象改变不会影响原型对象。然后,再修改克隆对象的值。
原型模式实现
Cloneable接口和clone方法
Prototype模式中实现起来最困难的地方就是内存复制操作,所幸在Java中提供了clone()方法替我们做了绝大部分事情。
注意用词:克隆和拷贝一回事!
原型模式(浅克隆)
Sheep.java
package com.cnki.prototype; import java.io.Serializable;
import java.util.Date; public class Sheep implements Cloneable, Serializable { // 1997,英国的克隆羊,多利! private static final long serialVersionUID = 1L;
private String sname;
private Date birthday; @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone(); // 直接调用object对象的clone()方法!
return obj;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Sheep(String sname, Date birthday) {
super();
this.sname = sname;
this.birthday = birthday;
} public Sheep() {
} }
Client.java
public class Client {
public static void main(String[] args) throws Exception {
Date date = new Date(12312321331L);
Sheep s1 = new Sheep("少利",date);
System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
//浅克隆带来的问题:修改s1生日后,s2生日也会改变
date.setTime(23432432423L);
System.out.println(s1.getBirthday());
Sheep s2 = (Sheep) s1.clone();
s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}
浅克隆存在的问题
被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
深克隆
深克隆把引用的变量指向复制过的新对象,而不是原有的被引用的对象。
深克隆:让已实现Clonable接口的类中的属性也实现Clonable接口
基本数据类型和String能够自动实现深度克隆(值的复制)

Sheep2.java
package com.cnki.prototype; import java.util.Date; //测试深复制
public class Sheep2 implements Cloneable { // 1997,英国的克隆羊,多利!
private String sname;
private Date birthday; @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone(); // 直接调用object对象的clone()方法!
// 添加如下代码实现深复制(deep Clone)
Sheep2 s = (Sheep2) obj;
s.birthday = (Date) this.birthday.clone(); // 把属性也进行克隆! return obj;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Sheep2(String sname, Date birthday) {
super();
this.sname = sname;
this.birthday = birthday;
} public Sheep2() {
}
}
Client2.java
public class Client2 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(12312321331L);
Sheep2 s1 = new Sheep2("少利", date);
Sheep2 s2 = (Sheep2) s1.clone(); // 实现深复制。s2对象的birthday是一个新对象!
System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
date.setTime(23432432423L);
System.out.println(s1.getBirthday());
s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}
利用序列化和反序列化技术实现深克隆
⑤ 设计模式的艺术-05.原型(Prototype)模式的更多相关文章
- 设计模式C++描述----08.原型(Prototype)模式
一. 概述 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 换句话说,就是不用重新初始化对象,而是动态地获得对象运行时的状态. 再说明白点,就是要一个拷贝过构造函数类似功能的接 ...
- Java 实现原型(Prototype)模式
public class BaseSpoon implements Cloneable {//spoon 匙, 调羹 String name; public String getName() { re ...
- 原型(Prototype)模式
原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象.这就是原型模式的用意.原型模式的结构 原型模式要求对象实现一个可以“克隆 ...
- 《图解设计模式》读书笔记3-2 Prototype模式
目录 Prototype(原型)模式的由来 类图 代码 角色 我的理解 Prototype(原型)模式的由来 创建一个实例,可以关键字new创建.但有时候,我们需要在不指定类名的前提下生成实例,比如: ...
- 设计模式--原型(Prototype)模式
写这些也许有人认为“为了模式而模式”.Insus.NET所想到的,每个大师成为大师之前,也许都得这样做. 走路,从小就开始学,直至现在,谁还不是为了走路而走路?一直重复着...... 很多人没有分享自 ...
- 六、原型(Prototype)模式
原型模式是对象的创建模式,通过给出一个原型对象来指明所要创建的对象的类型.然后用复制这个原型对象的方法来创建出更多同类型的对象. 原型模式可以不用重新初始化对象,而动态的获取对象运行时的状态.使用原型 ...
- 克隆复制可使用原型( Prototype)设计模式
今天有学习设计模式的原型(Prototype)<设计模式--原型(Prototype)模式>http://www.cnblogs.com/insus/p/4152773.html .为了加 ...
- 设计模式05: Prototype 原型模式(创建型模式)
Prototype 原型模式(创建型模式) 依赖关系的倒置抽象不应该依赖于实现细节,细节应该依赖于抽象.对所有的设计模式都是这样的. -抽象A直接依赖于实现细节b -抽象A依赖于抽象B,实现细节b依赖 ...
- 设计模式的征途—5.原型(Prototype)模式
相信大多数的人都看过<西游记>,对孙悟空拔毛变出小猴子的故事情节应该都很熟悉.孙悟空可以用猴毛根据自己的形象复制出很多跟自己一模一样的小猴兵出来,其实在设计模式中也有一个类似的模式,我们可 ...
随机推荐
- is-A继承?Has-A?
教程把is-A和Has-A放在一起,我还以为java支持简单的方法能把Has对象的方法导出呢.. extents implements 要试一下. 不知道狗和汽车为什么总是被选出来举例. p ...
- struts2 不返回result的做法
有时候 比如提交一个弹框的表单 提交成功后我们只是让表单关闭并不进行页面跳转,那么action 里面就returne null, 然后result 也不用配置了 版权声明:本文为博主原创文章,未经博主 ...
- 解决Ubuntu(Linux)平台下Sublime Text 3 安装中文输入支持库后 开启gnome-terminal报错的问题
在Ubuntu下安装Sublim Text3后发现无法输入中文,按照此链接的方法解决后.然后用下列代码配置C++的编译系统: { "cmd":["g++",&q ...
- PECE
CE客户端边界路由器.与PE设备直连,主要功能是将VPN客户的路由通告给PE,以及从PE学习同一个VPN下其他站点的路由.PE和CE直连的运营商设备(运营商边界路由器). #PE和CE也可以是用一台 ...
- The goal you specified requires a project to execute but there is no POM in this directory
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------- ...
- Java多线程 -sleep 用法详解
阿里面试官问我这个问题,我仔细总结了一下: 参考:sleep.yield.wait.join的区别(阿里面试) 我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确 ...
- SpingCloud之feign框架调用
1.生产者(没有什么特殊性) pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ...
- HDU4787_GRE Words Revenge
这个题目做得泪牛满面. 题目为给你若干串,有的表示添加一个串,有的表示询问一个串有多少个字串为前面出现过的串. 题目一看就知道肯定是AC自动机(不过后缀自动机也是可以的) 但是细想就会发现AC自动机好 ...
- kettle、Oozie、camus、gobblin
kettle简介 http://www.cnblogs.com/limengqiang/archive/2013/01/16/KettleApply1.html Oozie介绍 http://blog ...
- [十五]SpringBoot 之 启动加载数据
实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求. 为了解决这样的问题,spring Boot 为我们提供了一个方法,通过实现接口 CommandLineRunner 来 ...