原型模式使用手册,如何正确使用原型模式

原型模式属于创建型设计模式,可以重复的创建对象,并且保证效率。什么意思呢?也就是说,当我们大批量创建对象时,使用原型模式,会更高效。这里隐含1层含义:

1,当数据量达到一定规模是,原型模式创建对象的效率高于new对象。

 

真的吗,我们来试试。

 

首先创建2个bean,一个是普通的javabean,一个是实现了Cloneable接口的javabean

 

package com.yangcq.learning.hantang.learning;

import lombok.Data;

@Data
public class NormalNewObjectBean {

    public NormalNewObjectBean() {
        System.out.println("NormalNewObjectBean init");
    }
    /**
     * 商品编码
     */
    private String skuCode;

    /**
     * 商品名称
     */
    private String skuName;

    /**
     * 库存
     */
    private int quantity;

}

 

package com.yangcq.learning.hantang.learning;

import lombok.Data;

@Data
public class PrototypePatternBean implements Cloneable {

    public PrototypePatternBean() {
        System.out.println("PrototypePatternBean init");
    }
    /**
     * 商品编码
     */
    private String skuCode;

    /**
     * 商品名称
     */
    private String skuName;

    /**
     * 库存
     */
    private int quantity;

    @Override
    protected PrototypePatternBean clone(){

        PrototypePatternBean resume = null;
        try{
            resume = (PrototypePatternBean) super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }

        return resume;
    }
}

 

接下来,我们写个测试类,测试一下这2种方式创建对象的效率。

 

package com.yangcq.learning.hantang.learning;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class PrototypePatternMain {

    /**
     * 每个批次的记录数
     */
    private static final int BATCH_SIZE = 5000000;

    public static void main(String[] args) {

        LocalDateTime startTime = LocalDateTime.now();
        normalNewObject();
        log.info("normalNewObject 执行时间:{} 秒", (LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() -
                startTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) / 1000);

        LocalDateTime startTime2 = LocalDateTime.now();
        prototypePattern();
        log.info("prototypePattern 执行时间:{} 秒", (LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() -
                startTime2.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) / 1000);
    }

    /**
     * 原型模式
     */
    private static void prototypePattern() {

        PrototypePatternBean prototypePatternBean = new PrototypePatternBean();

        List<PrototypePatternBean> normalNewObjectBeans = new ArrayList<>();

        for (int i = 0; i < BATCH_SIZE; i++) {

            PrototypePatternBean prototypePatternBeanTemp = prototypePatternBean.clone();
            prototypePatternBeanTemp.setSkuCode("837474893");
            prototypePatternBeanTemp.setSkuName("华为meta40 pro 5G版 麒麟");
            prototypePatternBeanTemp.setQuantity(i);
            normalNewObjectBeans.add(prototypePatternBeanTemp);
        }

        System.out.println(normalNewObjectBeans.size());
    }

    /**
     * 普通方式new对象
     */
    private static void normalNewObject() {

        List<NormalNewObjectBean> normalNewObjectBeans = new ArrayList<>();

        for (int i = 0; i < BATCH_SIZE; i++) {
            NormalNewObjectBean normalNewObjectBean = new NormalNewObjectBean();
            normalNewObjectBean.setSkuCode("837474893");
            normalNewObjectBean.setSkuName("华为meta40 pro 5G版 麒麟");
            normalNewObjectBean.setQuantity(i);
            normalNewObjectBeans.add(normalNewObjectBean);
        }

        System.out.println(normalNewObjectBeans.size());

    }
}

运行一下,乖乖,差别还挺大。循环500万次,常规new对象方式耗时23秒,使用原型模式耗时0秒。

 

5000000
15:00:59.343 [main] INFO com.yangcq.learning.hantang.learning.PrototypePatternMain - normalNewObject 执行时间:23 秒
PrototypePatternBean init
5000000
15:00:59.536 [main] INFO com.yangcq.learning.hantang.learning.PrototypePatternMain - prototypePattern 执行时间:0 秒

 

但是我把构造函数中的控制台输出去掉以后,运行结果是这样的:

5000000
15:06:20.347 [main] INFO com.yangcq.learning.hantang.learning.PrototypePatternMain - normalNewObject 执行时间:0 秒
5000000
15:06:21.961 [main] INFO com.yangcq.learning.hantang.learning.PrototypePatternMain - prototypePattern 执行时间:1 秒

 

原型模式耗时反而高于常规的new对象方式。这是为什么呢?

原型模式创建对象时,不管你循环多少次,只会执行一次构造函数,也就是说,只会初始化一次。

new对象时,循环500万次,构造函数就会执行500万次。

 

也就是说,原型模式的好处就在于,省去了初始化的步骤,而是直接从内存中clone对象。从这里,我们也可以看出,

如果一个类的初始化流程比较复杂时,比如需要先执行父类中的模型逻辑,或者有复杂对象,需要进行数据库查询时,

那么,这时候选择原型模式,可以显著提高效率。

反之,如果只是一个简单的javabean,原型模式并没有优势。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值