Java设计模式-原型模式

最近学习到设计模式,现总结个人学习原型模式内容。
上一篇:Java设计模式-工厂模式

定义

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。理解:通过复制的方式创建的对象。原型模式明显更关心的是结果的一致性。

优缺点

优点

  • 向客户隐藏制造新实例的复杂性【用户对对象的创建过程不可见】
  • 在某些环境下,复制对象比创建新对象更有效【举例流程表单的流程对象】

例如这个实体类,就成员都将近150个,如果全都通过创建对象的方式,其工作量是不可估量的。
在这里插入图片描述

缺点

  • 需要为被克隆的目标类添加克隆方法,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
  • 在实现深克隆【深拷贝】时需要编写较为复杂的代码,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。

实现

先给定两个实体类

class Money implements Serializable,Cloneable{ 
	private static final long serialVersionUID = -4350061171177220007L;
	public String moneytype;
	public Double moneynum;
	Money(String moneytype,Double moneynum){
		this.moneytype=moneytype;
		this.moneynum=moneynum;
		}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
}
public class UserEntity implements Serializable,Cloneable{
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	private ArrayList<String> phonenumbers ;
	private ArrayList<Money> moneys ;
	private Money moeny;
}

浅拷贝

利用Object的clon方法

代码实现

/**
	 * 浅拷贝仅能拷贝八大基本数据类型+String
	 * 数据类型,其他数据类型直接引用地址
	 * 例如这里拷贝不了用户的电话号码集合
	 * @return
	 */
	public UserEntity getShallowCopy(){
		UserEntity copyentity = null;
		try {
			copyentity= (UserEntity) this.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return copyentity;
	}

测试

可以看到对拷贝后的数据进行修改,其中修改基本类型+String类型并没有影响到原始数据,但是对对象修改明显影响到 原始数据。这个就需要说到深拷贝的实现了,需要自己对对象的所有成员,进行递归式的浅拷贝
在这里插入图片描述

深拷贝

代码实现

/**
	 * 深拷贝,在浅拷贝了基本类型+String数据后,
	 * 需要对引用类型单独进行拷贝。但是如果引用类型中还存在引用依然非完全深拷贝
	 * @return
	 */
	public UserEntity getDeepCopy(){
		UserEntity copyentity = null;
		try {
			copyentity= (UserEntity) this.clone();
			copyentity.phonenumbers = (ArrayList<String>) this.phonenumbers.clone();
			copyentity.moneys = (ArrayList<Money>) this.moneys.clone();
			copyentity.moeny = (Money) this.moeny.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return copyentity;
	}

测试

从测试结果中,我们以及看到深拷贝需要对每一个成员中的对象进行克隆,同时自定义对象也需要实现clon方法,但是为什么对
在这里插入图片描述

字节码拷贝

代码实现

 * 利用序列化与反序列化实现
	 * @return
	 */
	public UserEntity getByteCopy(){
		ByteArrayOutputStream baos = null;
		ObjectOutputStream oos = null;
		
		ByteArrayInputStream bais = null;
		ObjectInputStream   ois = null;
		UserEntity copyentity = null;
		try {
			//序列化
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(this);
			
			//反序列化
			bais = new ByteArrayInputStream(baos.toByteArray());
			ois = new ObjectInputStream(bais);
			copyentity = (UserEntity)ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				oos.close();
				baos.close();
				bais.close();
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return copyentity;
	}

测试

在这里插入图片描述


日常对较大对象的拷贝尽量使用原型模式的方式,降低创建对象成本,较大对象的创建需要耗费cpu网络等,较大引起gc回收。

以上仅为个人学习,如果错误望指出,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值