設計模式(十三)[創建模式] 原型模式(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();
		}
	}
	
}

 

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