JAVA_设计模式_创建型_原型模式

26 篇文章 0 订阅

原型模式
将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。

1.编写测试所需JavaBean

实现Cloneable接口,重写clone方法
Sheep:模拟浅克隆
Sheep2:模拟深克隆

package com.bjsxt.prototype;

import java.io.Serializable;
import java.util.Date;

/**
 * 克隆羊多利
 * @author WL20180732
 *
 */
public class Sheep implements Cloneable, Serializable{
	private String sname;
	private Date birthdy;
	
	
	public Sheep(String sname, Date birthdy) {
		this.sname = sname;
		this.birthdy = birthdy;
	}


	public String getSname() {
		return sname;
	}


	public void setSname(String sname) {
		this.sname = sname;
	}


	public Date getBirthdy() {
		return birthdy;
	}


	public void setBirthdy(Date birthdy) {
		this.birthdy = birthdy;
	}


	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object obj = super.clone(); // 直接调用Object的克隆方法,浅克隆
		return obj;
	}
}


package com.bjsxt.prototype;

import java.util.Date;

/**
 * 测试深复制
 * @author WL20180732
 *
 */
public class Sheep2 implements Cloneable{
	private String sname;
	private Date birthdy;
	
	
	public Sheep2(String sname, Date birthdy) {
		this.sname = sname;
		this.birthdy = birthdy;
	}


	public String getSname() {
		return sname;
	}


	public void setSname(String sname) {
		this.sname = sname;
	}


	public Date getBirthdy() {
		return birthdy;
	}


	public void setBirthdy(Date birthdy) {
		this.birthdy = birthdy;
	}


	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object obj = super.clone(); // 直接调用Object的克隆方法
		
		// 添加如下代码实现深复制
		Sheep2 s = (Sheep2) obj;
		s.birthdy = (Date)this.birthdy.clone();  // 把属性也进行拷贝
		return obj;
	}
}

2.测试原型模式(浅克隆)
package com.bjsxt.prototype;

import java.util.Date;

/**
 * 测试原型模式(浅克隆)
 * @author WL20180732
 *
 */
public class Client {
	public static void main(String[] args) throws CloneNotSupportedException {
		Date date = new Date(122121545454L);
		Sheep sheep = new Sheep("少利", date);
		System.out.println(sheep);
		
		Sheep sheep2 = (Sheep) sheep.clone();
		sheep2.setSname("多利");
		System.out.println(sheep2);
		System.out.println(sheep2.getSname());
		
		System.out.println(date == sheep2.getBirthdy());  // true sheep和sheep2使用了同一个日期对象,所以是浅克隆
		System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
	}
}

3.测试深克隆
package com.bjsxt.prototype;

import java.util.Date;

/**
 * 原型模式(深拷贝)
 * @author WL20180732
 *
 */
public class Client2 {
	public static void main(String[] args) throws CloneNotSupportedException {
		Date date = new Date(122121545454L);
		Sheep2 sheep = new Sheep2("少利", date);
		Sheep2 sheep2 = (Sheep2) sheep.clone();
		
		date.setTime(1234567654321L);
		
		System.out.println(sheep.getBirthdy());  // sheep的出生日期更改不会影响sheep2
		System.out.println(sheep2.getBirthdy());
		System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
		
	}
}

4.使用序列化和反序列化的方式实现深复制
package com.bjsxt.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;

/**
 * 原型模式(深拷贝,使用序列化和反序列化的方式实现深复制)
 * @author WL20180732
 *
 */
public class Client3 {
	public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
		Date date = new Date(122121545454L);
		Sheep sheep = new Sheep("少利", date);
//		Sheep sheep2 = (Sheep) sheep.clone();
		// 使用序列化和反序列化实现深复制
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream os = new ObjectOutputStream(bos);
		os.writeObject(sheep);
		byte[] bytes = bos.toByteArray();
		
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
		ObjectInputStream ois = new ObjectInputStream(bis);
		Sheep sheep2 = (Sheep) ois.readObject();  // 克隆羊
		
		System.out.println(sheep.getBirthdy());
		date.setTime(1234567654321L);  //修改以前对象的属性,不会影响克隆羊
		
		System.out.println(sheep.getBirthdy());  // sheep的出生日期更改不会影响sheep2
		System.out.println(sheep2.getBirthdy());
		System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
		
	}
}

5.测试通过new和clone方法短时间创建大量对象的效率对比
package com.bjsxt.prototype;

/**
 * 测试通过new和clone方法短时间创建大量对象的效率对比
 * 如果需要短时间创建大量对象,且new的过程比较耗时,则clone的效率更高
 * @author WL20180732
 *
 */
public class Client4 {
	public static void main(String[] args) throws CloneNotSupportedException {
		testNew(1000);
		testClone(1000);
	}
	
	public static void testNew(int size) {
		long start = System.currentTimeMillis();
		for (int i = 0; i < size; i++) {
			Laptop t = new Laptop();
		}
		long end = System.currentTimeMillis();
		System.out.println("new方式创建耗时:" + (end - start) );
	}
	
	public static void testClone(int size) throws CloneNotSupportedException {
		long start = System.currentTimeMillis();
		Laptop t = new Laptop();
		for (int i = 0; i < size; i++) {
			Laptop temp = (Laptop) t.clone();
		}
		long end = System.currentTimeMillis();
		System.out.println("clone方式创建耗时:" + (end - start) );
	}
	
}

/**
 * 笔记本电脑
 * @author WL20180732
 *
 */
class Laptop implements Cloneable{
	public Laptop() {
		try {
			// 模拟创建一个该类对象非常耗时的场景
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值