Proto Type

package com.DesignPatterns;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * The prototype is typically used to clone an object, i.e. to make a copy of an
 * object. When an object is complicated or time consuming to be created , you
 * may take prototype pattern to make such object cloneable. Assume the Complex
 * class is a complicated, you need to implement Cloneable interface and
 * override the clone method(protected Object clone()).
 */
public class ProtoType {

	public static final int SHALLOW_COPY = 0;
	public static final int CLONEABLE_COPY = 1;
	public static final int SERIALIZABLE_COPY = 2;

	public static void printDatainfo(int copyType, Complex complex)
			throws CloneNotSupportedException, IOException,
			ClassNotFoundException {

		complex.id = 123;
		complex.city = "New York";
		complex.populations = new int[]{1, 2, 3, 4, 5};

		if (copyType == SHALLOW_COPY || copyType == CLONEABLE_COPY) {
			complex.clonedQuoted = new ClonedQuoted(456, "London");
		}
		if (copyType == SHALLOW_COPY || copyType == SERIALIZABLE_COPY) {
			complex.serializedQuoted = new SerializedQuoted(789, "Paris");
		}

		Complex copyedComplex = null;
		if (copyType == SHALLOW_COPY) {
			complex.isShallowCopy = true;
			copyedComplex = (Complex) complex.clone();
		} else if (copyType == CLONEABLE_COPY) {
			complex.isShallowCopy = false;
			copyedComplex = (Complex) complex.clone();
		} else if (copyType == SERIALIZABLE_COPY) {
			copyedComplex = (Complex) deepCopy(complex);
		}

		System.out.println("change String or int value:");
		complex.id = 321;
		complex.city = "纽约";
		System.out.println(complex);
		System.out.println(copyedComplex);
		System.out.println();

		System.out.println("change Array value:");
		complex.populations[0] = 5;
		System.out.println(complex);
		System.out.println(copyedComplex);
		System.out.println();

		if (copyType == SHALLOW_COPY || copyType == CLONEABLE_COPY) {
			System.out.println("change Cloneable Object value:");
			complex.clonedQuoted.id = 654;
			complex.clonedQuoted.city = "伦敦";
			System.out.println(complex);
			System.out.println(copyedComplex);
			System.out.println();
		}

		if (copyType == SHALLOW_COPY || copyType == SERIALIZABLE_COPY) {
			System.out.println("change Serializable Object value:");
			complex.serializedQuoted.id = 987;
			complex.serializedQuoted.city = "巴黎";
			System.out.println(complex);
			System.out.println(copyedComplex);
		}
	}

	public static Object deepCopy(Object obj) throws IOException,
			ClassNotFoundException {

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(obj);

		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);

		return ois.readObject();
	}

	public static void main(String[] args) throws CloneNotSupportedException,
			IOException, ClassNotFoundException {

		/**
		 * A shallow copy of the original object can only store the basic
		 * variable just as int, boolean, etc. If the cloned object changed the
		 * value of quoted object just as Array, list, etc, the original object
		 * will be changed accordingly, vice versa.
		 */
		Complex complex = new Complex();
		System.out.println("Shallow copy:");
		printDatainfo(SHALLOW_COPY, complex);

		/**
		 * To avoid such side effect, you may use a deep copy instead of a
		 * shallow copy. There are 2 ways to implement it.
		 */
		complex = new Complex();
		System.out.println();
		System.out
				.println("**********************************************************************************");
		System.out.println();
		System.out.println("Deep copy(implement by cloneable):");
		printDatainfo(CLONEABLE_COPY, complex);

		complex = new Complex();
		System.out.println();
		System.out
				.println("**********************************************************************************");
		System.out.println();
		System.out.println("Deep copy(implement by Serializable):");
		printDatainfo(SERIALIZABLE_COPY, complex);
	}
}

class Complex implements Cloneable, Serializable {

	static final long serialVersionUID = 1L;
	int id;
	String city;
	int[] populations;
	ClonedQuoted clonedQuoted;
	SerializedQuoted serializedQuoted;
	boolean isShallowCopy;

	@Override
	protected Object clone() throws CloneNotSupportedException {

		Complex complex = (Complex) super.clone();
		
		if (!isShallowCopy) {

			complex = (Complex) super.clone();
			complex.clonedQuoted = ((ClonedQuoted) complex.clonedQuoted.clone());
			complex.populations = complex.populations.clone();
		}
		return complex;
	}

	@Override
	public String toString() {

		String str = "Complex:{ {id=" + id + ", city="
				+ city + ", populations=";

		for (int i : populations) {
			str += i + ",";
		}
		str = str.substring(0, str.length() - 1) + "}*****";

		if (clonedQuoted != null) {
			str += "Cloned: {id=" + clonedQuoted.id + ", city="
					+ clonedQuoted.city + "}*****";
		}
		if (serializedQuoted != null) {
			str += "Serialized: {id=" + serializedQuoted.id
					+ ", city=" + serializedQuoted.city + "} }";
		}

		return str;
	}
}

class ClonedQuoted implements Cloneable {

	int id;
	String city;

	public ClonedQuoted() {
	}

	public ClonedQuoted(int id, String city) {
		this.id = id;
		this.city = city;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

class SerializedQuoted implements Serializable {

	static final long serialVersionUID = 2L;
	int id;
	String city;

	public SerializedQuoted() {
	}

	public SerializedQuoted(int id, String city) {
		this.id = id;
		this.city = city;
	}
}

你可能感兴趣的:(type)