使用場景:
多次創建重複的類,每個類又需要非常繁瑣的數據準備和訪問權限。
原型模式類似用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();
}
}
}