您的位置:首页 > 编程语言 > Go语言

【GOF23设计模式】原型模式

2016-08-24 12:30 316 查看
来源:http://www.bjsxt.com/
一、【GOF23设计模式】_原型模式、prototype、浅复制、深复制、Cloneable接口



浅复制

package com.test.prototype;

import java.util.Date;

/**
* 浅复制
*/
public class Sheep implements Cloneable{//Cloneable为标记接口
private String sname;
private Date birthday;

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

public Sheep() {
}

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

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;
}
}


package com.test.prototype;

import java.util.Date;
/**
* 测试原型模式(浅复制)
*/
public class Client {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep s1 = new Sheep("少利", date);
Sheep s2 = (Sheep) s1.clone();

System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()

s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}


控制台输出:s1修改时间后,s2的也跟着改(Fri Dec 10 00:59:15 CST 12500)

com.test.prototype.Sheep@1db9742
少利
Sun Feb 08 21:55:32 CST 1970
Fri Dec 10 00:59:15 CST 12500
com.test.prototype.Sheep@647e05
多利
Fri Dec 10 00:59:15 CST 12500


深复制

package com.test.prototype;

import java.util.Date;

/**
* 深复制
*/
public class Sheep2 implements Cloneable{//Cloneable为标记接口
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 Sheep2() {
}

public Sheep2(String sname, Date birthday) {
super();
this.sname = sname;
this.birthday = birthday;
}

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;
}
}


package com.test.prototype;

import java.util.Date;
/**
* 测试原型模式(深复制)
*/
public class Client2 {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep2 s1 = new Sheep2("少利", date);
Sheep2 s2 = (Sheep2) s1.clone();

System.out.println(s1);
System.out.println(s1.getSname());
System.out.println(s1.getBirthday());
date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改
System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()

s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}


控制台输出:s1修改时间后,s2还是最初的(Sun Feb 08 21:55:32 CST 1970)

com.test.prototype.Sheep2@1db9742
少利
Sun Feb 08 21:55:32 CST 1970
Fri Dec 10 00:59:15 CST 12500
com.test.prototype.Sheep2@647e05
多利
Sun Feb 08 21:55:32 CST 1970


二、【GOF23设计模式】_原型模式、反序列化实现深复制、效率对比、创建型模式总结
利用序列化和反序列化技术实现深复制

package com.test.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* 原型模式(使用序列化和反序列化的方式实现深复制)
*/
public class Client3 {
public static void main(String[] args) throws Exception {
Date date = new Date(3333332323L);
Sheep s1 = new Sheep("少利", date);

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

//      Sheep s2 = (Sheep) s1.clone();
//使用序列化和反序列化实现深复制
//序列化
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("修改原型对象的属性值");
date.setTime(332324355555555L);
System.out.println(s1.getBirthday());

s2.setSname("多利");
System.out.println(s2);
System.out.println(s2.getSname());
System.out.println(s2.getBirthday());
}
}


短时间大量创建对象时,原型模式和普通new方式效率测试:

package com.test.prototype;
/**
* 测试普通new方式创建对象和clone方式创建对象的效率差异!
* 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式!
*/
public class Client4 {

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));
}

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

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();//直接调用object对象的clone()方法
return obj;
}
}


控制台输出:

new的方式创建耗时:10168
clone的方式创建耗时:10


开发中的应用场景:
原型模式很少单独出现,一般和工厂模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
spring中bean的创建实际就是两种:单例模式和原型模式(原型模式需要和工厂模式搭配起来)。

创建型模式的总结:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: