Prototype原型模式和深克隆
来源:互联网 发布:所有香烟条形码数据库 编辑:程序博客网 时间:2024/06/06 06:32
原型模式通过给出一个原型对象来指明所要创建对象的类型,然后克隆该原型对象以便创建出更多同类型的新对象
主要执行克隆操作,实现创建新的对象
适用性
1.当一个系统应该独立于它的产品创建、构成和表示时。
2.当要实例化的类是在运行时刻指定时,例如,通过动态装载。
3.为了避免创建一个与产品类层次平行的工厂类层次时。
4.当一个类的实例只能有几个不同状态组合中的一种时。
建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
假 设一个系统的产品类是动态加载的,而且产品类具有一定的等极结构。这个时候如果采取工厂模式的话,工厂类就不得不具有一个相应的等级。而产品类的等级结构 一旦变化,工厂类的等级结构就不得不有一个相应的变化。这对于产品结构可能会有经常性变化的系统来说,采用工厂模式就有不方便之处。
这时如果采取原型模式,给每一个产品类配备一个克隆方法(大多数的时候只需给产品类等级结构的基类配备一个克隆方法),便可以避免使用工厂模式所带来的具有固定等级结构的工厂类。
原型模式是浅克隆,clone方法实现的复制是“浅拷贝”(浅克隆),也就是说克隆的不够彻底,被克隆出的对象中的变量和原来的对象中的变量有相同的值,但是克隆出的对象中的引用和原对象中的引用的指向是相同的,但是克隆出的对象等同new是新的物理地址
因此,使用原型模式克隆出的对象,物理地址是新的(clon==clon2 为 false),使用’==’比较两个对象的class类型(clon.getClass()==clon2.getClass())都是一样的为true,克隆出的对象中的引用和原对象中的引用的指向是相同的clon.getSub()==clon2.getSub() 为 true
原型对象的数据和克隆出的对象数据变化:
由于是浅克隆,所以当原型中的属性值变化时,被克隆对象的属性值是不变的(参考浅克隆案例),但如果原型中的引用对象发生变化,被克隆出的对象中的引用对象也会发生改变,因为克隆的不彻底,如果需要被克隆出的对象中的引用对象不变,就需要用深克隆实现(具体参考深克隆案例)
运用:
假 设一个系统的产品类是动态加载的,而且产品类具有一定的等极结构,这时使用原型模式比工厂模式更方便
https://www.2cto.com/kf/201212/172624.html这个链接对于克隆讲的比较详细
代码示例:
public class Prototype {
public static void main(String[] args) {
Clon clon = new Clon();
clon.setStr("helloworld");
Clon clon2 = (Clon) clon.clone();
System.out.println("clon.getClass()==clon2.getClass() ? "
+ (clon.getClass() == clon2.getClass()));
System.out.println("clon==clon2 ? " + (clon == clon2));
System.out.println("clon.getSub()==clon2.getSub() ? "
+ (clon.getSub() == clon2.getSub()));
System.out.println(clon.equals(clon2));
}
}
class Clon implements Cloneable {
private String str = null;
private substance sub = new substance();
public void setStr(String str) {
this.str = str;
}
public substance getSub() {
return sub;
}
public void printStr() {
System.out.println(str);
}
public Object clone() {
Clon to_clon = null;
try {
to_clon = (Clon) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e);
} finally {
return to_clon;
}
}
}
class substance {
}
深克隆代码示例:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//深克隆
public class CloneObject
{
/**
* 克隆对象
*/
public static Object deepClone(Object src)
{
Object o = null;
try
{
if (src != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(src);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
o = ois.readObject();
ois.close();
}
}
catch (IOException e)
{
//LOG.error("ServiceOper Occur an Exception when deepClone", e);
}
catch (ClassNotFoundException e)
{
//LOG.error("ServiceOper Occur an Exception when deepClone", e);
}
return o;
}
public static void main(String[] args)
{
UserInfo u1 = new UserInfo();
u1.setUserName("I'm u1");
UserInfo u2 = (UserInfo)deepClone(u1);
System.out.println(u2.getUserName());
}
}
//该类实现序列化接口
class UserInfo implements Serializable
{
private static final long serialVersionUID = 1L;
private String userName;
private String age;
public String getUserName(){
return userName;
}
public void setUserName(String userName){
this.userName = userName;
}
public String getAge(){
return age;
}
public void setAge(String age){
this.age = age;
}
}
- Prototype原型模式和深克隆
- 对象的克隆--原型模式(Prototype)
- Java 深复制(深克隆)&浅复制(浅克隆)&原型模式(ProtoType)
- 原型模式-浅克隆和深克隆的自我理解
- 原型模式的浅克隆和深克隆
- Prototype原型克隆
- 原型模式-Prototype Pattern 对象的克隆——原型模式(三):带附件的周报【浅克隆,深克隆】
- 原型模式-Prototype Pattern 对象的克隆——原型模式(四):原型管理器的引入和实现,原型模式总结
- Qt C++ prototype(原型模式或者克隆模式)
- 深入浅出设计模式 ------ Prototype(原型模式)之深度克隆
- JAVA设计模式---原型模式--浅客隆和深克隆
- [设计模式](四):建造者模式(Builder)与原型模式(Prototype)[含Kotlin深克隆实例代码]
- java设计模式学习笔记--原型模式(浅克隆和深克隆)
- 创建模式之原型模式 深克隆
- 原型模式-Prototype Pattern 对象的克隆——原型模式(一):大同小异的工作周报,原型模式概述
- 原型模式-Prototype Pattern 对象的克隆——原型模式(二):工作周报的原型模式解决方案
- 设计模式之原型模式(深克隆,浅克隆)
- 原型模式 Prototype模式
- [bzoj2096][Poi2010]Pilots(二分+单调队列)
- 35个Java代码性能优化总结
- 【Hibernate】数据库配置
- 计蒜客 Minimum Distance in a Star Graph 2017icpc南宁赛区 字符串bfs
- [kuangbin带你飞]专题17:A
- Prototype原型模式和深克隆
- 深入理解vue.js双向绑定的实现原理
- Linux 中模拟延时和丢包的实现
- bzoj 1570: [JSOI2008]Blue Mary的旅行 分层图网络流
- bzoj1212 [HNOI2004]L语言(AC+dp)
- 双向链表的小练习
- 创建maven-web项目eclipse 版本 Version: Oxygen Release
- 谈谈我的保研经历
- springMVC中controller的几种返回方式