原型模式

北战南征 提交于 2020-03-24 09:30:14

3 月,跳不动了?>>>

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。  原型模式通过内存二进制流进行拷贝,不用经历对象初始化过程(不用调用构造函数);性能有所提升。

    原型模式包括客户、抽象原型、具体原型3种角色:
    客户:客户端提出创建对象的请求
    抽象原型:规定拷贝接口
    具体原型:被拷贝的对象

优点:
    1、原型模式比基于二进制流拷贝,java自带的,比直接new一个对象性能性能好。
    2、可以使用深克隆方式拷贝一个对象保存其状态,简化创建流程。需要的时候可以恢复到克隆保存的对象数据。可辅助实现撤销操作。
缺点:
    1、需要对克隆的类配置一个方法。
    2、克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码。违背开闭原则。
    3、当对象有多重嵌套的时候,需要使用到深克隆使用比较麻烦。浅克隆对嵌套对象复制的只是一个引用地址。需权衡使用深克隆和浅克隆。
应用场景:
    1、类初始化消耗资源较多
    2、new产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)
    3、构造函数比较复杂
    4、循环体中生产大量对象时。

代码示例:

浅克隆(实现Cloneable接口重写clone方法)


@Data
public class CloneEntity implements Cloneable{
    
    private String name;
    
    private List<String> names;
    
    @Override
    protected CloneEntity clone() throws CloneNotSupportedException {
        return (CloneEntity)super.clone();
    }
}

    public static void main(String [] args){
        try {
            CloneEntity cloneEntity=new CloneEntity();
            cloneEntity.setName("test");
            List<String> list= new ArrayList<>();
            list.add("zhangshan");
            list.add("lisi");
            cloneEntity.setNames(list);

            System.out.println("-----------浅克隆-----------------");
            CloneEntity clone = cloneEntity.clone();
            clone.setName("clone_test");
            clone.getNames().add("wangwu");
            System.out.println("原对象:"+cloneEntity.toString());
            System.out.println("浅克隆对象:"+clone.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    }
输出:
-----------浅克隆-----------------
原对象:CloneEntity(name=test, names=[zhangshan, lisi, wangwu])
浅克隆对象:CloneEntity(name=clone_test, names=[zhangshan, lisi, wangwu])

深克隆(通过序列化克隆)    

@Data
public class CloneEntity implements Cloneable{
    
    private String name;
    
    private List<String> names;
    
    public CloneEntity 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 (CloneEntity)ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public CloneEntity jsonClone(){
        try {
            String jsonObj= JSONObject.toJSONString(this);
            return JSONObject.parseObject(jsonObj,this.getClass());
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

    public static void main(String [] args){
        try {
            CloneEntity cloneEntity=new CloneEntity();
            cloneEntity.setName("test");
            List<String> list= new ArrayList<>();
            list.add("zhangshan");
            list.add("lisi");
            cloneEntity.setNames(list);
    
            System.out.println("-----------深克隆-----------------");
            CloneEntity deepClone = cloneEntity.jsonClone();
            deepClone.setName("clone_test");
            deepClone.getNames().add("wangwu");
            System.out.println("原对象:"+cloneEntity.toString());
            System.out.println("浅克隆对象:"+deepClone.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    }
输出:
-----------深克隆-----------------
原对象:CloneEntity(name=test, names=[zhangshan, lisi])
浅克隆对象:CloneEntity(name=clone_test, names=[zhangshan, lisi, wangwu])

源码中应用案例
ArrayList实现了Cloneable接口(浅克隆)

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

HashMap实现了Cloneable接口(浅克隆)

    public Object clone() {
        HashMap<K,V> result;
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
        result.reinitialize();
        result.putMapEntries(this, false);
        return result;
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!