设计模式学习--------10.原型模式学习

场景:

      一个订单系统,里面有一个保存订单的业务功能。具体需求:每当订单的预订产品超过1000的时候,需要把订单拆分

成两份订单。如果拆分成两份后还是超过1000,则继续拆分。订单类型分为个人订单和公司订单,不管是什么类型的订

单,都要能够正常地处理.抽象的描述下就是已经有了某个对象实例后,如何能够快速的创建出更多的这种对象。


定义:

      用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。


角色:

Prototype: 声明一个克隆自身的接口,用来约束想要克隆自己的类,要求他们都要实现这里定义的克隆方法。

package com.kris.study;

public interface Prototype {
     public Prototype cloneItem();
     public void display();
}


ConcretePrototype:实现Prototype接口的类,这些类真正实现了克隆自身的功能

package com.kris.study;

public class ConcretePrototype2 implements Prototype {

	@Override
	public Prototype cloneItem() {
		return new ConcretePrototype2();
	}

	@Override
	public void display() {
		System.out.println("ConcretePrototype2 display");
	}

}

 

package com.kris.study;

public class ConcretePrototype1 implements Prototype {
	
	@Override
	public Prototype cloneItem() {
		return new ConcretePrototype1();
	}

	@Override
	public void display() {
		System.out.println("ConcretePrototype1 display");
	}

}


Client客户端:

package com.kris.study;

public class Client {
	private Prototype prototype;

	public Client(Prototype prototype){
		this.prototype = prototype;
	}
	
	public void operation(){
		Prototype newPrototype = prototype.cloneItem();
		newPrototype.display();
	}
	
}


使用JAVA中的克隆方法实现原型模式解决场景的问题:

Order:订单类

package com.kris.study;

public abstract class Order implements Cloneable{
	private String productId;
	private int orderProductNum = 0;
	
	public abstract void setName(String name);
	public abstract String display();
	
	public String getProductId() {
		return productId;
	}
	public void setProductId(String productId) {
		this.productId = productId;
	}
	public int getOrderProductNum() {
		return orderProductNum;
	}
	public void setOrderProductNum(int orderProductNum) {
		this.orderProductNum = orderProductNum;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}


PersonalOrder:个人订单类

package com.kris.study;

public class PersonalOrder extends Order {

	 private String personalName;
	    
		@Override
		public String display() {
		  return "PersonalName:"+personalName;
		}


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

		
}


EnterpriseOrder:公司订单类

package com.kris.study;

public class EnterpriseOrder extends Order {
    private String enterpriseName;
    
	@Override
	public String display() {
	  return "EnterpriseName:"+enterpriseName;
	}


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


OrderBiz:订单业务

package com.kris.study;

public class OrderBiz {
   public void saveOrder(Order order){
	   while(order.getOrderProductNum()>1000){
		try {
			Order newOrder = (Order) order.clone();
			newOrder.setOrderProductNum(1000);
			order.setOrderProductNum(order.getOrderProductNum()-1000);
			System.out.println("new order info ==> name: "+newOrder.display()+" productId:"
					+newOrder.getProductId()+" productNum:"+newOrder.getOrderProductNum());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	   }
	   System.out.println("old order info ==> name: "+order.display()+" productId:"
				+order.getProductId()+" productNum:"+order.getOrderProductNum());
   }
}


Client:客户端

package com.kris.study;

public class Client {
   public static void main(String[] args) {
	 Order order = new PersonalOrder();
	 order.setName("John");
	 order.setProductId("111");
	 order.setOrderProductNum(3422);
	 new OrderBiz().saveOrder(order);
   }
}


深克隆和浅克隆

浅克隆:只负责克隆按值传递的数据(比如基本数据类型,String类型)。

深克隆:除了浅克隆要克隆的值外,还负责克隆引用类型的数据。

引用类型需要递归实现Cloneable接口。

JAVA中实现深克隆:

package com.kris.study;

public class Product implements Cloneable {
    private String productId;
    private String name;
	public String getProductId() {
		return productId;
	}
	public void setProductId(String productId) {
		this.productId = productId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "Product [productId=" + productId + ", name=" + name + "]";
	}
    
    @Override
    public Object clone() throws CloneNotSupportedException {
    	return super.clone();
    }
}

 

package com.kris.study;

public class PersonalOrder implements Cloneable {
     private String customerName;
     private Product product = null;
	public String getCustomerName() {
		return customerName;
	}
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	public Product getProduct() {
		return product;
	}
	public void setProduct(Product product) {
		this.product = product;
	}
	
	@Override
	public String toString() {
		return "PersonalOrder [customerName=" + customerName + ", product="
				+ product + "]";
	}
	
	@Override
	public Object clone() throws CloneNotSupportedException {
		PersonalOrder obj = (PersonalOrder) super.clone();
		//关键的一句话
		obj.setProduct((Product) this.product.clone());
		return obj;
	}
		
}


原理分析:

   本质:克隆生成新对象

   优点:对客户端隐藏具体实现

   缺点:每个原型的子类必须实现clone的操作。

   

 

posted @ 2014-05-10 16:43  Leo的银弹  阅读(201)  评论(0编辑  收藏  举报