场景:
一个订单系统,里面有一个保存订单的业务功能。具体需求:每当订单的预订产品超过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的操作。