原型模式
一、定义
原型模式是一种创建型设计模式。能够复制已有对象, 而又无需使代码依赖它们所属的类。
二、问题
有一个订单系统,当订单中的货品数量大于1000时,那么该系统就会分拆成两个订单,如果还大于1000再拆分…… 订单:id,货物名称,数量 货物:id,货物名称
三、解决方案
我们就可以使用克隆来完成对订单的复制。 创建一系列不同类型的对象并不同的方式对其进行配置。 如果所需对象与预先配置的对象相同, 那么你只需克隆原型即可, 无需新建一个对象。 支持克隆的对象即为原型(该问题中为订单)
注意:克隆时需要注意深浅拷贝的问题! 浅拷贝:拷贝基本数据类型 如 id,数量 深拷贝:拷贝引用数据类型 如 货物
四、代码实现
1、原型 (Prototype) 接口将对克隆方法进行声明。 在绝大多数情况下, 其中只会有一个名为 clone克隆的方法。
这里使用的是Java自带的克隆接口
package java.lang;
public interface Cloneable {
}
2、具体原型 (Concrete Prototype) 类将实现克隆方法。
package com.atmae.prototype;
public class Order implements Cloneable {
public Order(Long id, Product product, Integer num) {
this.id = id;
this.product = product;
this.num = num;
}
private Long id;
private Product product;
private Integer num;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", product=" + product +
", num=" + num +
'}'+'\n';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Order order = (Order) super.clone();
order.product= (Product) this.product.clone();
return order;
}
}
3、客户端
package com.atmae.prototype;
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Product product = new Product("面包", 10001L);
Order order = new Order(10000L, product, 6600);
List<Order> orders = new ArrayList<>();
int num=1;
while (order.getNum() > 1000) {
Order o = (Order) order.clone();
o.setNum(1000);
o.setId(order.getId()+num);
order.setNum(order.getNum() - 1000);
orders.add(o);
num++;
}
orders.add(order);
System.out.println(orders);
}
}
五、UML图
六、原型模式适用场景
- 需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类
七、总结
优点
- 可以克隆对象, 而无需与它们所属的具体类相耦合。
- 可以克隆预生成原型, 避免反复运行初始化代码。
- 可以更方便地生成复杂对象。
- 可以用继承以外的方式来处理复杂对象的不同配置。
缺点
八、与其他模式的比较
- 与工厂方法模式
原型并不基于继承, 因此没有继承的缺点。 另一方面, 原型需要对被复制对象进行复杂的初始化。 工厂方法基于继承, 但是它不需要初始化步骤。 原型可以起到工厂模式的效果。
|