设计模式之原型模式

设计模式之原型模式

原型模式

通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
即Java中的克隆技术,以某个对象为原型,复制出新对象,新对象具有原对象的特点;
优势:效率高

原型模式实现:
Cloneable接口和clone()方法

Sheep:

package com.prototype;

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

//多利羊
public class Sheep implements Cloneable,Serializable {
private String name;
private Date birthday;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public Sheep(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}

//重写clone()函数:浅克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
}

Sheep2:

 @Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();//直接调用object对象的clone()方法

//添加如下代码实现深复制
Sheep2 s = (Sheep2) obj;
s.birthday = (Date) this.birthday.clone();

return obj;
}

Client:

/**
 * 测试浅克隆
 */
package com.prototype;

import java.util.Date;

public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(1997);
Sheep s1 = new Sheep("多利",date);

Sheep s2 = (Sheep) s1.clone();//克隆s1

System.out.println(s1);
System.out.println(s1.getName());
System.out.println(s1.getBirthday());

date.setTime(98868768);

System.out.println(s1.getBirthday());
System.out.println("----------------------");


System.out.println(s2);
s2.setName("少利");//修改名字
System.out.println(s2.getName());
System.out.println(s2.getBirthday());
}
}

结果:

com.prototype.Sheep@4554617c
多利
Thu Jan 01 08:00:01 CST 1970
Fri Jan 02 11:27:48 CST 1970
----------------------
com.prototype.Sheep@7f31245a
少利
Fri Jan 02 11:27:48 CST 1970

原型对象内容改变时,新对象也跟着改变

Client2

/**
 * 测试深克隆
 */
package com.prototype;

import java.util.Date;

public class Client2 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(1997);
Sheep2 s1 = new Sheep2("多利",date);

Sheep2 s2 = (Sheep2) s1.clone();//克隆s1

System.out.println(s1);
System.out.println(s1.getName());
System.out.println(s1.getBirthday());

date.setTime(98868768);
System.out.println(s1.getBirthday());

System.out.println("----------------------");

System.out.println(s2);
s2.setName("少利");//修改名字
System.out.println(s2.getName());
System.out.println(s2.getBirthday());
}
}

结果:

com.prototype.Sheep2@4554617c
多利
Thu Jan 01 08:00:01 CST 1970
Fri Jan 02 11:27:48 CST 1970
----------------------
com.prototype.Sheep2@7f31245a
少利
Thu Jan 01 08:00:01 CST 1970

原型对象内容改变时,新对象不改变

Client3:

/**
 * 测试深克隆(通过序列化和反序列化实现深克隆)
 */
package com.prototype;

import java.io.*;
import java.util.Date;

public class Client3 {
public static void main(String[] args) throws Exception {
Date date = new Date(1997);
Sheep s1 = new Sheep("多利",date);

//Sheep2 s2 = (Sheep2) s1.clone();//克隆s1
//通过序列化和反序列化实现深克隆
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[] bytes = bos.toByteArray();

ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Sheep s2 = (Sheep) ois.readObject();

System.out.println(s1);
System.out.println(s1.getName());
System.out.println(s1.getBirthday());

date.setTime(98868768);
System.out.println(s1.getBirthday());

System.out.println("----------------------");

System.out.println(s2);
s2.setName("少利");//修改名字
System.out.println(s2.getName());
System.out.println(s2.getBirthday());
}
}

结果:

com.prototype.Sheep@135fbaa4
多利
Thu Jan 01 08:00:01 CST 1970
Fri Jan 02 11:27:48 CST 1970
----------------------
com.prototype.Sheep@3feba861
少利
Thu Jan 01 08:00:01 CST 1970

原型对象内容改变时,新对象不改变

Client4:

/**
 * 短时间大量创建对象时,原型模式和普通new方式效率测试
 */
package com.prototype;

public class Client4 {

//使用new方法创建Laptop对象
public static void testNew(int size) {
long start = System.currentTimeMillis();//开始时间
Laptop laptop = new Laptop();
for(int i=0;i<size;i++) {
Laptop temp = new Laptop();
}
long end = System.currentTimeMillis();//结束时间
System.out.println("new耗时:"+(end-start));
}

//使用clone()创建Laptop对象
public static void testClone(int size) throws CloneNotSupportedException {
long start = System.currentTimeMillis();
Laptop laptop = new Laptop();
for(int i=0;i<size;i++) {
Laptop temp = (Laptop) laptop.clone();
}
long end = System.currentTimeMillis();
System.out.println("clone()耗时:"+(end-start));
}

public static void main(String[] args) throws CloneNotSupportedException {
testNew(100);
testClone(100);
}

}

//笔记本
class Laptop implements Cloneable {
//构造函数
public Laptop(){
try {
Thread.sleep(10);//模拟创建对象耗时过程
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
}

结果:

new耗时:1100
clone()耗时:11

如果需要短时间创建大量对象,并且new的过程比较耗时,可以考虑使用原型模式

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值