使用场景:
多次创建重复的类,每个类又需要非常繁琐的数据准备和访问权限。
原型模式类似用new创建出来的类,但又不new的类,new出来的类属性都是默认值,而用原型模式克隆出来的类,属性都和原对象一样。原型模式的优点是复制类效率高,而且避免重复无聊的new类动作
下面,我们使用原型模式来clone一个类,这里的demo既有深复制也有浅复制
首先是我们复制的实体类
package com.javademo.pattern.prototype;
import java.io.Serializable;
/**
* Cloneable,clone浅复制需要用
* Serializable序列话和反序列化需要用
* @author liuxg
* @date 2016年5月24日 下午9:29:19
*/
@SuppressWarnings("serial")
public class User implements Cloneable ,Serializable {
private String name ;
private int age ;
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null ;
}
}
public User(String name, int age) {
this.name = name ;
this.age = age ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接下来写测试类
package com.javademo.pattern.prototype;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream;
/**
* 原型模式测试
* @author liuxg
* @date 2016年5月24日 下午9:27:21
*/
public class Client01 {
public static void main(String[] args) {
Client01 client01 = new Client01() ;
client01.lightCopy();
client01.deepCopy();
}
/**
* 浅复制,只能复制类,但类的属性还是指向同一个地址
*
*/
private void lightCopy(){
User user = new User("liuxg",18);
User uclone = (User)user.clone();
//user.setName("liuxg2"); //重新把user的name设置为liuxg2.发现uclone下的name也变成了liuxg2,所有user和uclone指向的同一个地址
System.out.println(uclone.getName() + " : " + uclone.getAge());
}
/**
* 深复制,除了复制类,还复杂属性,使用的时候java的序列化和反序列化
*/
private void deepCopy(){
try {
User user = new User("liuxg",18);
//序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(user);
//反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
User uclone = (User) ois.readObject();
//user.setName("liuxg2"); //user的name变成liuxg2,uclone的name还是liuxg,说明属性也进行不了复制,没有指向同一个地址
System.out.println(uclone.getName() + " : " + uclone.getAge());
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}