zoukankan      html  css  js  c++  java
  • 原型模式(Prototype Pattern)

    原型模式(Prototype Pattern)

    通过拷贝创建新的对象,调用者不用知道创建细节,不调用构造函数,是一种创建型模式,简而言之就是一个克隆一个对象,使用场景

    • 类初始化消耗资源过多
    • 构造函数比较复杂
    • 循环体中产生大量新的对象

    对于原型模式有两种写法,一种浅克隆(克隆对象使用的指向的同一个地址)一种深克隆(克隆对象的内容,地址不同),在【深度拷贝带随机指针的链表】 中我曾经提到。

    Shallow clone

    @Data
    @ToString
    public class ConcretePrototype implements Cloneable {
    
        private int age;
        private String name;
        private List<String> hobbies;
    
        @Override
        protected ConcretePrototype clone()  {
            try {
                return (ConcretePrototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return  null;
            }
        }
    }

    To test

    public class Client {
        public static void main(String[] args) {
            ConcretePrototype concretePrototype=new ConcretePrototype();
            concretePrototype.setAge(18);
            concretePrototype.setName("Glen");
            List<String> hobbies=new ArrayList<String>();
            hobbies.add("Girls");
            hobbies.add("Techniques");
            concretePrototype.setHobbies(hobbies);
    
            ConcretePrototype concretePrototype1=concretePrototype.clone();
            concretePrototype1.getHobbies().add("man");
            System.out.println(concretePrototype+"initial..");
            System.out.println(concretePrototype1+"cloned..");
            // They are different space of memory
            System.out.println(concretePrototype==concretePrototype1);
            // for primary data type can be pointed to different space of memory but specific type can not be (they remain point to the same space,such List)
            System.out.println(concretePrototype.getHobbies()==concretePrototype1.getHobbies());
        }
    }

    To explain:

    apparently,for instance, They are different spaces,but for specific, They are same space,so according conclusion,we get that it use shallow clone in basis of jdk for specific type,actually jdk just copy value of address of memory, like value of 'int boolean、char、float、double'  are saved in value of address of memory,but some specific types like List, in fact, their  value of address of memory are saved their value of addres,so just copy their value of addres cause same scenario of  value of addres.

     Deep clone

     method of serialization 

    @Data
    @ToString
    public class ConcretePrototype implements Cloneable,Serializable {
    
        private int age;
        private String name;
        private List<String> hobbies;
    
        ConcretePrototype deepClone()  {
            ByteOutputStream byteOutputStream=new ByteOutputStream();
            try {
                ObjectOutputStream objectOutput=new ObjectOutputStream(byteOutputStream);
                objectOutput.writeObject(this);
                ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteOutputStream.getBytes());
                ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
                return (ConcretePrototype) objectInputStream.readObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    To test

    public class Client {
        public static void main(String[] args) {
            ConcretePrototype concretePrototype=new ConcretePrototype();
            concretePrototype.setAge(18);
            concretePrototype.setName("Glen");
            List<String> hobbies=new ArrayList<String>();
            hobbies.add("Girls");
            hobbies.add("Techniques");
            concretePrototype.setHobbies(hobbies);
            // We just replace the method of our cloning
            ConcretePrototype concretePrototype1=concretePrototype.deepClone();
            concretePrototype1.getHobbies().add("man");
            System.out.println(concretePrototype+"initial..");
            System.out.println(concretePrototype1+"cloned..");
            System.out.println(concretePrototype==concretePrototype1);
            System.out.println(concretePrototype.getHobbies()==concretePrototype1.getHobbies());
        }
    }

     To explain

    We use  serialization to create the classess, do you remember that we had mentioned the method in singleton (use serialization  to destroy),so that we can not make a classess to be both singleton and  prototype!! do you remember that if we override 'readResolve' what is the result, Right! The 'java.io.ObjectInputStream#readObject0' will not create the new classess, so we must not override 'readResolve'

    Be applied into the souce of code

    java.util.ArrayList#clone

     java.util.HashMap#clone

     

     We find out that resouce of code above both Override the 'java.lang.Object#clone' so can we  Override that then add our logical code in it?definitely

        ConcretePrototype deepCloneHobbies() {
            try {
                ConcretePrototype clone = (ConcretePrototype) super.clone();
                clone.hobbies=(List)((ArrayList)clone.getHobbies()).clone();
                return clone;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

     Hi,we solve it perfectly,but if there are many specific type in the same class, do you want to do it more?so, personally, i think we use  method of serialization more complete!

    Sum up

    advantage

    • Be base on Binary stream to copy more  efficient than  to create a instance
    • To simplify process of creating a class

    disadvantage

      we must add a method of clone in each classess in order to with clone to create classess

     

  • 相关阅读:
    求得分除以总分的百分比
    考试用时存入秒数,最后用方法转换一成这种格式 (00:00:00)
    微信生成二维码 只需一个网址即刻 还有jquery生成二维码
    微信公众号整套逻辑的支付和退款
    thinkphp 无限极 评论
    新版谷歌浏览器怎么查找和改变编码格式 IT开发人员谷歌的编码格式
    【bzoj2199】[Usaco2011 Jan] 奶牛议会
    BZOJ1997 [Hnoi2010]Planar (2-sat)
    uvalive 3211 Now or later
    codeforce 660D Number of Parallelograms
  • 原文地址:https://www.cnblogs.com/UpGx/p/14664144.html
Copyright © 2011-2022 走看看