美文网首页
创建型之原型模式

创建型之原型模式

作者: FisherTige_f2ef | 来源:发表于2020-12-15 18:23 被阅读0次

    原型模式(Prototype Pattern)

    不需要经过构造函数创建实例,直接在内存中拷贝对象实例,常用于为了创建重复的对象,又要保证较高性能的场景。

    优点: 1、性能提高。 2、逃避构造函数的约束。

    缺点:如果复制的对象 里面又有引用其他对象,然后引用的其他对象再有其他对象的引用(有很多层),需要考虑以下问题:1、复制需要深入多少层。2、如何避免出现循环引用的问题

    使用场景: 1、资源优化场景,对于一个已存在内存中的类实例,需要创建多个实例提供给其他对象访问,而且各个调用者可能都需要修改其值时,但是类初始化需要消化非常多的资源,这个资源包括硬件资源、非常繁琐的数据准备或访问权限等,可以考虑使用原型模式拷贝多个对象供调用者使用。

     java最常见的原型模式实现就是深拷贝与浅拷贝。

    浅拷贝

    在内存层面对一个对象进行拷贝,对象有着原始对象基本类型数据的一份精确拷贝,及引用类型的内存地址拷贝。即如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址。因此,如果其中一个对象改变了这个地址,就会影响到另一个对象。

    实现方式:重写Clone方法

    public class ShallowClone implements Cloneable {

                public int a;  // 基本类型

                public int[]b; // 非基本类型

                // 重写Object.clone()方法,并把protected改为public

                @Override

                public Objectclone(){

                            ShadowClone sc =null;

                            try{

                                    sc = (ShallowClone)super.clone();

                            }catch (CloneNotSupportedException e){

                                    e.printStackTrace();

                            }

                    return sc;

            }

    }

    深拷贝

    在内存层面对一个对象进行拷贝,对象有着原始对象基本类型数据的一份精确拷贝,及引用类型的内存地址指向的内存数据。即如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址指向的内存数据。因此,如果其中一个对象改变了这个地址,不会影响到另一个对象。

    实现方式:

    1、重写Clone方法

    class Bottle implements Cloneable {

        public Wine wn;

        public Bottle(Wine wn){

            this.wn = wn;

        }

        // 覆写clone()方法

        @Override

        protected Object clone() throws CloneNotSupportedException{

            Bottle newBtl = (Bottle)super.clone();

            newBtl.wn = (Wine) wn.clone();

            return newBtl;

        }

    }

    class Wine implements Cloneable {

        int degree;

        public int getDegree() {

            return degree;

        }

        public void setDegree(int degree){

            this.degree = degree;

        }

        // 覆写clone()方法

        @Override

        protected Object clone() throws CloneNotSupportedException{

            return super.clone();

        }

    }

    2、采用序列化方式,例如serializable、 Parcelable、ProtoBuf等

    class DeepPerson implements Serializable {

        private int a;

        private int[] b;

        public DeepPerson(){

        }

        public DeepPerson(int a, int[] b){

            this.a = a;

            this.b = b;

        }

        public int getA(){

            return a;

        }

        public void setA(int a){

            this.a = a;

        }

        public int[] getB(){

            return b;

        }

        public void setB(int[] b){

            this.b = b;

        }

    }

    public static void main(String[] args) throws CloneNotSupportedException{

            DeepPerson dc1 = new DeepPerson();

            // 对dc1赋值

            dc1.setA(100);

            dc1.setB(new int[]{ 1000 });

            System.out.println("克隆前dc1: a=" + dc1.getA()+"b[0]=" + dc1.getB()[0]);

            DeepPerson dc2 = (DeepPerson) deepClone(dc1);

            // 对c2进行修改

            dc2.setA(50);

            int[] a = dc2.getB();

            a[0] =500;

            System.out.println("克隆后dc1: a=" + dc1.getA()+"b[0]=" + dc1.getB()[0]);

            System.out.println("克隆后dc2: a=" + dc2.getA()+"b[0]=" + dc2.getB()[0]);

        }

    public static Object deepClone(Objectobject){

            Object o=null;

            try{

                if (object !=null){

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    ObjectOutputStream oos = new ObjectOutputStream(baos);

                    oos.writeObject(object);

                    oos.close();

                    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

                    ObjectInputStream ois = new ObjectInputStream(bais);

                    o = ois.readObject();

                    ois.close();

                }

            } catch (IOException e){

                    e.printStackTrace();

            } catch (ClassNotFoundException e) {

                    e.printStackTrace();

            }

            return o;

            }

    }

    相关文章

      网友评论

          本文标题:创建型之原型模式

          本文链接:https://www.haomeiwen.com/subject/gdkxiktx.html