美文网首页设计模式
原型模式及使用案例

原型模式及使用案例

作者: 文景大大 | 来源:发表于2022-06-02 13:19 被阅读0次

一、模式介绍

原型模式是一种创建型的模式,其核心在于快速复制对象。在Java中创建一个对象的方式有如下几种:

  • 通过new关键字调用类的构造函数进行创建;
  • 通过实现Cloneable接口重写clone方法进行创建;
  • 通过反射调用newInstance进行创建;
  • 通过反序列化进行对象的创建;

本文的原型模式就是基于第二种方式进行的,该方式是直接基于原始对象在内存中的二进制流直接复制得到拷贝对象,其内容和原始对象完全一致,对比第一种方式,效率更高,无需重复对属性进行赋值操作。原型模式主要适用如下场景:

  • 通过构造器创建对象的成本比较大,比如创建过程中时间、CPU、网络资源占用过多;
  • 创建一个对象需要繁琐的数据准备或者权限设置等;
  • 系统中需要大量使用该对象的副本,且各个调用者需要给它们各自的副本进行属性重新赋值;

原型模式通常实现方式如下:

@Data
public class Person implements Cloneable{
    private String name;
    private String country;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
@Slf4j
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person jack = new Person();
        jack.setName("jack");
        jack.setCountry("china");
        // 原始对象为:Person(name=jack, country=china)
        log.info("原始对象为:{}", jack);

        Person mason = (Person)jack.clone();
        mason.setName("mason");
        // 克隆对象为:Person(name=mason, country=china)
        log.info("克隆对象为:{}", mason);
        // 原始对象为:Person(name=jack, country=china)
        log.info("原始对象为:{}", jack);
    }
}

这里可以看到,原始对象jack进行clone后,得到的拷贝对象mason是完全复制的其属性的,mason在修改个别属性后,就完成了自己对象的初始化,就可以进行使用了,无论是复制还是修改,效率都比new提升了不少。

需要注意的是,Cloneable接口提供的clone方法,默认实现的是浅拷贝,只有基本数据类型和基本包装类型是完全复制的,对于引用类型则不是完全拷贝的,具体细节可以参考浅拷贝和深拷贝的常见使用方式 - 简书 (jianshu.com)

二、使用案例

2.1 ArrayList

ArrayList中包含了一个clone方法,基本就类似我们上面写的代码:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
    
        /**
     * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
     * elements themselves are not copied.)
     *
     * @return a clone of this <tt>ArrayList</tt> instance
     */
    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
}

根据代码和注释我们也能看到,这是一种浅克隆的原型模式。

2.2 Spring的原型模式

spring默认bean的获取方式是单例的,我们可以通过设置将其改为原型模式,那么每次getBean获取的对象就是完全新的对象。

源码地址尚未找到,后续补充。

三、使用总结

3.1 优点

  • 基于内存二进制流复制,性能上高于new一个对象的方式;
  • 克隆的对象保存了其属性状态,简化了创建对象的过程。

3.2 缺点

  • 需要为每一个类配置clone方法,当类发生变更时,有可能需要修改clone内容,违反了开闭原则;
  • 深度克隆需要自己重写clone方法,如果嵌套多层引用对象,实现起来会比较麻烦;

相关文章

  • 原型模式及使用案例

    一、模式介绍 原型模式是一种创建型的模式,其核心在于快速复制对象。在Java中创建一个对象的方式有如下几种: 通过...

  • 设计模式第五篇-创建型模式【原型模式】

    设计模式案例分析-github 一、什么是原型模式? 官方定义: 使用原型实例指定创建对象的种类,并且通过拷贝这...

  • 创建对象的几种方式

    1.工厂模式 使用方式 2.构造函数(缺点:每个方法需要在原型上构建一遍,重复) 使用方式及测试 3.原型模式(原...

  • JavaScript中new操作符的详细过程

    理解new对象过程,需要提前了解原型及原型链的相关知识 我们都知道,JS当中创建对象使用的是原型设计模式,即使用n...

  • 24种设计模式及案例

    24种设计模式及案例 24种设计模式及案例

  • 第3章 创建型模式-原型模式

    一、原型模式简介 二、原型模式的优点 ■ 三、原型模式的使用场景 ■ 四、原型模式的实例

  • 设计模式之原型模式(Prototype 模式)

    引入原型模式 原型模式的实例 为什么需要使用原型模式 引入原型模式 如果读者很熟悉javascript的话,对原型...

  • 设计模式原型模式

    1.原型模式的定义及使用场景定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象使用场景:类初始化需...

  • Java架构师课程

    Java架构班开学典礼 Spring中常用的设计模式概述及工厂模式详解 单例模式及原型模式单例模式及原型模式单例模...

  • 关于JavaScript创建对象的多种方式

    JavaScript创建对象的方法 工厂模式 构造函数模式 原型模式 组合使用构造函数模式和原型模式 动态原型模式...

网友评论

    本文标题:原型模式及使用案例

    本文链接:https://www.haomeiwen.com/subject/vedqmrtx.html