设计模式-创建型模式-原型(Prototype)模式及Java中原型模式的更多实现方式

1、前言

当需要克隆100个名称为Dolly 年龄 1的羊,以往的写法都是直接new 100个Sheep对象;

public class PrototypeDemo {
    public static void main(String[] args) {
        // 克隆100个 名称为Dolly 年龄 1;
        Sheep dolly1 = new Sheep("Dolly", 1);
        Sheep dolly2 = new Sheep("Dolly", 1);
        Sheep dolly3 = new Sheep("Dolly", 1);
        Sheep dolly4 = new Sheep("Dolly", 1);
        // ...
        Sheep dolly100 = new Sheep("Dolly", 1);
    }
    @Data
    static
    class Sheep {
        private String name;

        private int age;
    
        public Sheep (String name,int age){
            this.name = name;
            this.age = age;
        }
    }
}
  • 优点
    • 代码直观,易于理解
  • 缺点
    • 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低
    • 总是需要重新初始化对象,而不是动态地获得对象运行时的状态,不够灵活

2、什么是原型模式

原型模式(Prototype Pattern)通过拷贝这些原型,创建新的对象,是用于创建重复的对象,同时又能保证性能。原型模式属于创建型模式,它提供了一种创建对象的最佳方式。

原型模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

Java中Object类提供了一个clone()方法,该方法可以将一个Java对象复制一份,但是需要实现clone的Java类必须要实现一个接口Cloneable,该接口表示该类能够复制且具有复制的能力

  • 原型模式的实例的拷贝包括

    • 浅复制:将一个对象复制后,其基本数据类型的变量都会重新创建,而引用类型的变量指向的还是原对象所指向的,也就是指向的内存堆地址没变。
    • 深复制:将一个对象复制后,不论是基本数据类型还是引用类型,都是重新创建的
  • 通过实现Cloneable接口,Java默认的实现方式是浅复制,而非深复制。由于Object并没有实现Cloneable接口,所以子类必须实现Cloneable,并调用基类的clone方法才能实现浅复制。

3、原型模式实现


/**
 * 原型模式
 * @author liushiwei
 */
public class PrototypeDemo {
    public static void main(String[] args) throws Exception {
        prototype();
    }
    private static void prototype() throws Exception {

        ArrayList arrayList = new ArrayList();
        arrayList.add("foreFoot");
        Sheep dolly1 = new Sheep("Dolly", 1,arrayList);
        // 对象深拷贝
        Sheep dolly2 = (Sheep)dolly1.clone();
        ArrayList list = dolly2.getListFoot();
        list.add("hindFoot2");

        // 序列化的方式深拷贝
        Sheep dolly3 = (Sheep)dolly1.deepClone();
        ArrayList list3 = dolly3.getListFoot();
        list3.add("hindFoot3");

        System.out.println(dolly1 == dolly2);
        // 验证是拷贝类型,结果浅拷贝
        System.out.println("dolly1.list="+dolly1.getListFoot());
        System.out.println("dolly2.list="+dolly2.getListFoot());
        System.out.println("dolly3.list="+dolly3.getListFoot());
    }

    private static void tradition() {
        // 克隆100个 名称为Dolly 年龄 1;
        Sheep dolly1 = new Sheep("Dolly", 1,null);
        Sheep dolly2 = new Sheep("Dolly", 1,null);
        Sheep dolly3 = new Sheep("Dolly", 1,null);
        Sheep dolly4 = new Sheep("Dolly", 1,null);
        // ...
        Sheep dolly100 = new Sheep("Dolly", 1,null);
    }

}

public class Sheep implements Cloneable, Serializable {

    private String name;

    private int age;

    private ArrayList listFoot;

    public Sheep (){

    }

    public Sheep (String name,int age,ArrayList listFoot){
        this.name = name;
        this.age = age;
        this.listFoot = listFoot;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public ArrayList getListFoot() {
        return listFoot;
    }

    public void setListFoot(ArrayList listFoot) {
        this.listFoot = listFoot;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Sheep sheep = (Sheep)super.clone();
        // 对listFoot深拷贝
        sheep.listFoot = (ArrayList) this.listFoot.clone();

        return sheep;
    }

    /**
     * 通过序列化的方式 深拷贝
     * @return
     */
    protected Object deepClone() throws Exception{

        //把对象写入到字节流中
        ByteArrayOutputStream baos =new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(this);

        //把字节流转化为对象
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Sheep) ois.readObject();
    }

}

4、原型模式优缺点

  • 原型模式的优点:

    • 提高了创建对象的性能,避免了调用构造器创建对象。

    • 对于创建一个对象需要很多资源的情况,可以减少资源的浪费。

  • 原型模式的缺点:

    • 如果使用Cloneable接口的方式,需要实现Cloneable接口,对代码有一定的侵入性。

    • 如果使用序列化方式,则需要实现Serializable接口,对代码也有一定的侵入性。

5、原型模式的更多实现

  • Spring
    Sheep dolly4 = new Sheep();
    BeanUtils.copyProperties(dolly1,dolly4);
    ArrayList list4 = dolly4.getListFoot();
    list4.add("hindFoot4");
    System.out.println("list4.list="+dolly4.getListFoot());
    
  • fastjson
    • 通过JSONObject.parseObject方法实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值