读《研磨设计模式》-代码笔记-原型模式

声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/




/**
 * Effective Java 建议使用copy constructor or copy factory来代替clone()方法:
 * 1.public Product copy(Product p){}
 * 2.public static Product newInstance(Product p){} 
 */
public class PrototypePattern {

	private Product product;
	
	public PrototypePattern(Product product) {
		this.product = product;
	}
	
	public void saveProduct() {
		Product product2 = (Product) product.clone();
		System.out.println("Product Name before save:" + product2.getName());
		product2.setName("newProductName");
		System.out.println("Product Name after save:" + product2.getName());
		Label label2 = product2.getLabel();
		label2.setName("newLabelName");
	}
	
	public static void main(String[] args) {
		Label label = new Label();
		label.setName("labelName");
		Product product = new Product();
		product.setName("productName");
		product.setLabel(label);
		PrototypePattern client = new PrototypePattern(product);
		client.saveProduct();
		System.out.println("original product name is " + product.getName());
		System.out.println("original label name is " + product.getLabel().getName());
		
	}

}

/*
 * 1、java.lang.Cloneable是个空接口
 * 如果你不实现这个接口的话,调用clone方法的时候会出现CloneNotSupportedException
 * 2、clone()方法是Object的方法
 */
class Label implements Cloneable{
	
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Object clone() {
		Object object = null;
		try {
			object = super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return object;
	}
}

class Product implements Cloneable{
	
	private Label label;
	
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Label getLabel() {
		return label;
	}

	public void setLabel(Label label) {
		this.label = label;
	}
	
	//override Object的clone方法。手工克隆所有的field
	public Product clone() {
		Product p = new Product();
		p.setName(name);
		p.setLabel((Label)label.clone());	//深度克隆
		return p;
	}
	
	/*
	//也可这样写
	public Object clone() {
		Product other = null;
		try {
			
			//这一步是shallow copy。自动把name属性复制了。name是String类型,是"immutable object",否则就要像复制Label那样来复制
			other = (Product)super.clone();		
			
			//下面的操作不可少,否则新旧的Product里面的Label是同一个
			//而Label是mutable object,一个Product调用getLabel().setName()会影响到另一个Product
			other.label = (Label) this.label.clone();		
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return other;
	}
	*/
}

你可能感兴趣的:(java,设计模式)