侧边栏壁纸
博主头像
DJ's Blog博主等级

行动起来,活在当下

  • 累计撰写 133 篇文章
  • 累计创建 51 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

【设计模式】原型模式

Administrator
2022-03-18 / 0 评论 / 0 点赞 / 83 阅读 / 2568 字

【设计模式】原型模式

定义

  • 原型实例指定创建对象的种类,通过拷贝这些原型创建新的对象
  • 调用者不需要知道任何创建细节,不调用构造函数
  • 创建型模式

类图

适用场景

  • 类初始化消耗资源较多
  • new产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)
  • 构造函数比较复杂
  • 循环体中生产大量对象

代码实现

浅克隆

  • 原型实现Cloneable接口
public class ConcretePrototype implements Cloneable
  • 覆盖clone方法,如下所示
/**
 * 浅克隆
 * @return
 */
@Override
public ConcretePrototype clone() {
    try {
        return (ConcretePrototype) super.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return null;
}

深克隆

  • 序列化方式
/**
 * 深克隆
 * @return
 */
public ConcretePrototype deepClone() {
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);

        return (ConcretePrototype) ois.readObject();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

优点

  • 性能比使用构造器创建对象好很多。
  • 将对象使用深克隆,在某些业务场景下可以辅助实现撤销操作。

缺点

  • 需要为每个类配置一个clone()方法。
  • 在实现深克隆的时候,当对象属性比较复杂,并且存在多重对象嵌套的时候,深克隆的代码会变得很复杂。

源码中应用

  • ArrayList实现了Cloneable接口,它的clone()方法实现如下
/**
 * 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);
    }
}

通过注释可知,它是一个浅克隆

备注

  • 单例和原型是互斥的关系,如果是单例则不能实现Cloneable接口。
0

评论区