原型设计模式

Gof 原文

Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.

使用背景

Prototype design pattern is used when the Object creation is a costly affair and requires a lot of time and resources and you have a similar object already existing.
原型模式的核心在于复制原型对象。当对象的构建过程比较耗时时,可以把当前系统中已存在的对象作为原型,对其进行复制(一般是基于二进制流的复制),躲避耗时的对象初始化过程,使得新对象的创建时间大大缩短,性能提升许多。

要求

原型设计模式要求要复制的对象必须提供复制特性。然而,使用对象属性的浅拷贝还是深拷贝取决于需求和设计决策。

import org.apache.commons.lang3.SerializationUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Employees implements Cloneable, Serializable {

    private final List<String> empList;

    public Employees() {
        empList = new ArrayList<String>();
    }

    public Employees(List<String> list) {
        this.empList = list;
    }

    public void loadData() {
        //read all employees from database and put into the list
        empList.add("Pankaj");
        empList.add("Raj");
        empList.add("David");
        empList.add("Lisa");
    }

    public List<String> getEmpList() {
        return empList;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        List<String> temp = new ArrayList<>();
        for (String s : this.getEmpList()) {
            temp.add(s);
        }
        return new Employees(temp);
    }

    public Object deepClone() {
        try {
            return SerializationUtils.clone(this);
        } catch (Exception e) {
            // 更详细的错误处理
            System.err.println("Error cloning object: " + e.getMessage());
            // 可以选择记录日志或者返回null
            return null;
        }
    }

    public Object deepClone2() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            return ois.readObject();

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Employees emps = new Employees();
emps.loadData();
Employees empsNew = (Employees) emps.deepClone();
List<String> list = empsNew.getEmpList();
list.add("John");

Employees empsNew1 = (Employees) emps.deepClone();
List<String> list1 = empsNew1.getEmpList();
list1.remove("Pankaj");

System.out.println("emps List: "+emps.getEmpList());
System.out.println("empsNew List: "+list);
System.out.println("empsNew1 List: "+list1);

emps List: [Pankaj, Raj, David, Lisa]
empsNew List: [Pankaj, Raj, David, Lisa, John]
empsNew1 List: [Raj, David, Lisa]

原型模式在框架源码中的应用

我们找源码其实只需要看哪些接口实现了Cloneable即可。来看ArrayList类的实现。

    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);
        }
    }

原型模式在Spring源码中的应用

在Spring中,原型模式应用得非常广泛,例如scope="prototype"JSON.parseObject(),都是原型模式的具体应用。

参考

digitalocean - Prototype Design Pattern

在这里插入图片描述

关于Clone

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值