1.什麼是原型模式?
通過給出一個一個原型對象來指明所要創建的對象的類型,然後用複製這個原型對象的辦法創建出更多同類型的對象。
2.簡單形式的原始模型
- 客戶(Client)角色:客戶類提出創建對象的請求。
- 抽象(Prototype)原型角色:這是一個抽象角色,通常由一個Java接口或Java抽象類實現。此角色給出所有的具體原型類所需的接口。
- 具體原型(Concrete Prototype)角色:被複制的對象。此角色需要實現抽象的原型角色所要求的接口。
public interface Prototype extends Cloneable{
public Object clone();
}
public class Client1 {
private Prototype prototype;
public void operation(Prototype example) {
Prototype p = (Prototype)example.clone();
}
}
public class ConcretePrototype implements Prototype{
@Override
protected Object clone() {
try {
return super.clone();
}catch (Exception e) {
// TODO: handle exception
return null;
}
}
}
public interface Prototype extends Cloneable{
Prototype clone();
}
3.登記形式的原始模型模式
- 客戶端(Client)角色:客戶端類向管理員提出創建對象的請求。
- 抽象原型(Prototype)角色:這是一個抽象角色,通常由一個接口或抽象類實現。此角色給出所有的具體原型類所需的接口。
- 具體原型(Concrete Prototype)角色:被複制的對象。需要實現抽象的原型角色所要求的接口。
- 原型管理器(Prototype Manager)角色:創建具體原型類的對象,並記錄每一個被創建的對象。
public interface Prototype extends Cloneable{
public Object clone();
}
public class ConcretePrototype implements Prototype{
@Override
public synchronized Object clone() {
Prototype temp = null;
try {
temp = (Prototype) super.clone();
return temp;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}finally {
return temp;
}
}
}
import java.util.Vector;
public class PrototypeManager {
@SuppressWarnings("rawtypes")
private Vector objects=new Vector();
@SuppressWarnings("unchecked")
public void add(Prototype object) {
objects.add(object);
}
public Prototype get(int i) {
return (Prototype) objects.get(i);
}
public int getSize() {
return objects.size();
}
}
public class Client {
private PrototypeManager mgr;
private Prototype prototype;
public void registerPrototype() {
prototype = new ConcretePrototype();
Prototype copytype = (Prototype) prototype.clone();
mgr.add(copytype);
}
}
4.淺複製(淺克隆)
被複制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用都仍然指向原來的對象。換言之,淺複製僅僅複製所考慮的對象,而不復制它所引用的對象。
public class GoldRingedStaff {
private float height=100.0F;
private float diameter=10.0F;
public GoldRingedStaff() {
}
public void grow() {
this.diameter*=2.0;
this.height*=2;
}
public void shrink() {
this.diameter/=2;
this.height/=2;
}
public void move() {
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getDiameter() {
return diameter;
}
public void setDiameter(float diameter) {
this.diameter = diameter;
}
}
import java.util.Date;
public class Monkey implements Cloneable{
private int height;
private int weight;
private GoldRingedStaff staff;
private Date birthDate;
public Monkey() {
super();
}
public Monkey(Date birthDate) {
super();
this.birthDate = birthDate;
}
@SuppressWarnings("finally")
public Object clone() {
Monkey temp=null;
try {
temp = (Monkey) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}finally {
return temp;
}
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
}
import java.util.Date;
public class TheGreatestSage {
private Monkey monkey = new Monkey(new Date());
public void change() {
Monkey copyMonkey;
for(int i=0;i<1000;i++) {}
copyMonkey=(Monkey) monkey.clone();
System.out.println(monkey.getBirthDate());
System.out.println(copyMonkey.getBirthDate());
System.out.println(monkey==copyMonkey);
System.out.println(monkey.getStaff()==copyMonkey.getStaff());
}
public static void main(String[] args) {
TheGreatestSage sage = new TheGreatestSage();
sage.change();
}
}
5.深複製(深克隆)
被複制對象的所有的變量都含有與原來的對象的相同的值,除去那些引用其他對象的變量。那些引用其他對象的變量將指向被複制過的新對象,而不再是原有的那些被引用的對象。換言之,深複製把要複製的對象所引用的對象都複製一遍,而這種對被引用的對象的複製叫間接複製。
import java.io.Serializable;
public class GoldRingedStaff implements Cloneable,Serializable{
private float height=100.0F;
private float diameter=10.0F;
public GoldRingedStaff() {
}
public void grow() {
this.diameter*=2.0;
this.height*=2;
}
public void shrink() {
this.diameter/=2;
this.height/=2;
}
public void move() {
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getDiameter() {
return diameter;
}
public void setDiameter(float diameter) {
this.diameter = diameter;
}
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
public class Monkey implements Cloneable,Serializable{
private int height;
private int weight;
private GoldRingedStaff staff;
private Date birthDate;
public Monkey() {
this.birthDate = new Date();
this.staff = new GoldRingedStaff();
}
public Object deepClone() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
@SuppressWarnings("finally")
public Object clone() {
Monkey temp=null;
try {
temp = (Monkey) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}finally {
return temp;
}
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
}
import java.io.IOException;
import java.util.Date;
public class TheGreatestSage {
private Monkey monkey = new Monkey();
public void change() throws ClassNotFoundException, IOException {
Monkey copyMonkey;
for(int i=0;i<1000;i++) {}
copyMonkey=(Monkey) monkey.deepClone();
System.out.println(monkey.getBirthDate());
System.out.println(copyMonkey.getBirthDate());
System.out.println(monkey==copyMonkey);
System.out.println(monkey.getStaff()==copyMonkey.getStaff());
}
public static void main(String[] args) {
TheGreatestSage sage = new TheGreatestSage();
try {
sage.change();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}