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