• 原型模式


    一、概念与通用格式

    本章借鉴了《大话设计模式》之外,也借鉴了这篇博客https://www.cnblogs.com/lfxiao/p/6812835.html

    原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型 创建新的对象。

    这相当于是对一个对象“复制黏贴”,新的对象有自己的引用地址。

    当对象创建比较复杂时,可使用原型模式。

    如图:

    注意:clone()里return不能return this;这样就相当于把原来的对象地址传过来,return的还是原来的对象,不是新的引用地址。

    当每次new一个对象,都需要执行一次构造函数,如果构造函数执行的时间很长,那么多次操作就降低了效率。一般在初始化的信息不发生变化的情况下,克隆是很好的办法,既隐藏了对象创建的细节,又提高了性能。

    二、java提供的接口

    当然,像这样常用的模式,java一定给了相应的接口 Cloneable。

    Java语言提供的clone():

    package cn.sasa.prototypeTest;
    
    public class ConcretePrototype2 implements Cloneable{
        private int id;
        
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public Object clone() {
            Object cloneObj = null;
            try {
                cloneObj = super.clone();
            } catch (CloneNotSupportedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return cloneObj;
        }
    }

    三、浅复制与深复制

    假设 我们再加一个类Pet,作为ConcretePrototype2的一个成员

    package cn.sasa.prototypeTest;
    
    import java.io.Serializable;
    
    public class Pet implements Serializable{
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private String petName;
    
        public String getPetName() {
            return petName;
        }
    
        public void setPetName(String petName) {
            this.petName = petName;
        }
    
    }

    客户端测试:

    我们发现,复制的新的对象和原来的是不一样的内存地址,但是对象里的引用类型的成员,clone过来的是原对象的内存地址,这就是浅复制

    即浅复制是:如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用,但不复制引用的对象。

    由于浅复制的引用类型成员引用的同一地址,如果更改其中一个,原模板对象也随之改变。

     深复制是和浅复制相对的,这里引用这篇博客的截图,https://www.cnblogs.com/lfxiao/p/6812835.html

     所以代码修改如下:

    package cn.sasa.prototypeTest;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class ConcretePrototype2 implements Cloneable,Serializable{
    
        private static final long serialVersionUID = 1L;
        private int id;
        private String name;
        private Pet pet;
        
        public ConcretePrototype2() {
            pet = new Pet();
        }
        
        public Pet getPet() {
            return pet;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
        
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void SetPetName(String petName) {
            this.pet.setPetName(petName);
        }
        
        
        public Object clone() {
            Object cloneObj = null;
            try {
                cloneObj = super.clone();
            } catch (CloneNotSupportedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return cloneObj;
        }
        
        public ConcretePrototype2 deepClone() throws IOException, ClassNotFoundException {
            //将对象写入流中
    
            ByteArrayOutputStream bao=new  ByteArrayOutputStream();
    
            ObjectOutputStream oos=new  ObjectOutputStream(bao);
    
            oos.writeObject(this);
    
           
    
            //将对象从流中取出
    
            ByteArrayInputStream bis=new  ByteArrayInputStream(bao.toByteArray());
    
            ObjectInputStream ois=new  ObjectInputStream(bis);
    
            return  (ConcretePrototype2)ois.readObject();
        }
    
        
    }

    测试:

  • 相关阅读:
    vscode中golang插件配置
    好用的go开源模块汇总
    常用linux指令
    读大嘴生平咨询---->关于商业模式的思考
    photoprism 源码阅读
    C语言的算法
    C语言输出函数和输入函数
    C语言基本概念
    servlet(3)
    servlet(2)
  • 原文地址:https://www.cnblogs.com/SasaL/p/10682838.html
Copyright © 2020-2023  润新知