设计模式:原型模式

设计模式:原型模式


定义

原型模式的定义:Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)

结构类图

原型模式的通用类图:

原型模式的通用类图

原型模式非常简单,它的核心是一个clone方法,通过该方法完成对象的拷贝,在Java中只需要实现Cloneable接口,并且覆盖Object类的clone方法。

通用源码

原型模式的通用源码:

public class PrototypeClass implements Cloneable {

    //覆写父类Object方法
    @Override
    protected PrototypeClass clone() {
        PrototypeClass prototypeClass = null;
        try {
            prototypeClass = (PrototypeClass) super.clone();
        } catch (CloneNotSupportedException e) {
            // 异常处理
        }
        return prototypeClass;
    }

}

实现Cloneable接口,然后重写clone方法,就完成了原型模式!

应用场景举例

比如客户提供订单交给工厂处理。订单有产品的数量和名称,公司接受订单后需要保存最原始的数据作为存根。公司每个部门在一个订单内最多只能生产1000个产品,所以需要将原始订单进行拆分,然后处理。

抽象订单类IOrder,定义订单数量和clone操作:

public interface IOrder extends Cloneable {

    int getOrderNumber();

    void setOrderNumber(int orderNumber);

    IOrder clone();
}

产生两个订单实现类,个人订单类PersonalOrder:

public class PersonalOrder implements IOrder {

    private String orderName;
    private int orderNumber;

    @Override
    public int getOrderNumber() {
        return orderNumber;
    }

    @Override
    public void setOrderNumber(int orderNumber) {
        this.orderNumber = orderNumber;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    @Override
    public IOrder clone() {
        IOrder order = null;
        try {
            order = (IOrder) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return order;
    }
}

公司订单类CompanyOrder:

public class CompanyOrder implements IOrder {

    private String orderName;
    private int orderNumber;

    @Override
    public int getOrderNumber() {
        return orderNumber;
    }

    @Override
    public void setOrderNumber(int orderNumber) {
        this.orderNumber = orderNumber;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    @Override
    public IOrder clone() {
        IOrder order = null;
        try {
            order = (IOrder) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return order;
    }
}

订单处理类OrderDealFactory,将原始订单进行拆分处理:

public class OrderDealFactory {

    public void dealOrder(IOrder order) {
        int number = order.getOrderNumber();
        while (number > 0) {
            /**
             * 如果不使用原型模式,需要根据实际类型new对象,来保存原始数据
            if (order instanceof PersonalOrder) {
                IOrder iOrder = null;
                PersonalOrder personalOrder = (PersonalOrder) order;
                PersonalOrder newOrder = new PersonalOrder();
                newOrder.setOrderName(personalOrder.getOrderName());
                newOrder.setOrderNumber(number >= 1000 ? 1000 : number);
                iOrder = personalOrder;
                System.out.println("原始订单: " + iOrder.getOrderNumber());
                System.out.println("newOrder number = " + newOrder.getOrderNumber());
                number -= 1000;
            }
             */

            IOrder newOrder = (IOrder) order.clone();
            newOrder.setOrderNumber(number >= 1000 ? 1000 : number);
            System.out.println("原始订单: " + order.getOrderNumber());
            System.out.println("newOrder number = " + newOrder.getOrderNumber());
            number -= 1000;
        }
    }

}

场景类的调用方法如下:

public class Client {

    public static void main(String[] args) {
        OrderDealFactory factory = new OrderDealFactory();
        PersonalOrder order = new PersonalOrder();
        order.setOrderName("个人订单");
        order.setOrderNumber(3200);
        factory.dealOrder(order);
    }

}

浅拷贝、深拷贝

Object类的clone方法的原理是从内存中(具体地说就是堆内存)以二进制流的方式进行拷贝,重新分配一个内存块。所以是浅拷贝,拷贝对象内部的引用对象是不会被拷贝的。即:浅拷贝前后的对象,内部的数组和引用对象,指向的还是同一片内存。

总结

  • 原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多。
  • 在上面的例子中,增加一个订单类,订单处理类不需要修改,符合开闭原则。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值