设计模式(十三)[创建模式] 原型模式(Prototype)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章