美文网首页
原型模式

原型模式

作者: 我可能是个假开发 | 来源:发表于2023-11-20 10:38 被阅读0次

    一、定义

    复制运行时的对象,克隆出一个一模一样的对象;
    hashcode和引用地址不同,只有内容相同。

    UML.png

    原型模式:

    • 浅克隆:创建一个新对象,新对象的地址指向原来的引用
    • 深克隆:重新创建一个对象,不再指向原有的对象地址

    基于二进制流,比new快

    二、实现

    实现Cloneable接口
    对象克隆:

    public class PrototypeImpl implements Cloneable {
    
        private ArrayList list = new ArrayList();
    
        @Override
        public PrototypeImpl clone() {
    
            PrototypeImpl prototype = null;
            try {
                // 对象克隆
                prototype = (PrototypeImpl)super.clone();
                // 克隆集合
                // 数组,容器,集合,对象引用需要另行克隆
                prototype.list =  (ArrayList)this.list.clone();
            }catch (CloneNotSupportedException e){
                e.printStackTrace();
            }
            return prototype;
        }
    }
    
    public class CreatePrototype extends PrototypeImpl {
        public void show(){
            System.out.println("原型模式的实现类......");
        }
    }
    
    public class TestDemo {
        public static void main(String[] args) throws CloneNotSupportedException {
            CreatePrototype prototype = new CreatePrototype();
            // 克隆出一个新的对象
            CreatePrototype prototype1= (CreatePrototype)prototype.clone();
            prototype1.show();
        }
    }
    

    三、深度克隆

    public class Person implements Cloneable{
    
        private String name;
    
        private Child child;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Child getChild() {
            return child;
        }
    
        public void setChild(Child child) {
            this.child = child;
        }
    
        @Override
        protected Person clone() {
            try {
                return (Person) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", child=" + child +
                    '}';
        }
    
        public Person(String name) {
            this.name = name;
        }
    }
    
    public class Child implements Cloneable{
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Child(String name) {
            this.name = name;
        }
    
        @Override
        protected Child clone() {
            try {
                return (Child) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString() {
            return "Child{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Person person = new Person("父亲");
            person.setChild(new Child("孩子"));
    
            //Person{name='父亲', child=Child{name='孩子'}}
            System.out.println(person);
    
            Person clonePerson = person.clone();
    
            //Person{name='父亲', child=Child{name='孩子'}}
            System.out.println(clonePerson);
    
            //false
            System.out.println(person==clonePerson);
        }
    }
    

    浅克隆:
    存在的问题:复制的是引用地址,会导致克隆对象的修改影响了原有对象。

    public class Test {
    
        public static void main(String[] args) {
            Person person = new Person("父亲");
            person.setChild(new Child("孩子"));
    
            //person:Person{name='父亲', child=Child{name='孩子'}}
            System.out.println("person:"+person);
    
            Person clonePerson = person.clone();
            clonePerson.getChild().setName("孩子2");
    
            //clonePerson:Person{name='父亲', child=Child{name='孩子2'}}
            System.out.println("clonePerson:"+clonePerson);
            
            //person:Person{name='父亲', child=Child{name='孩子2'}}
            System.out.println("person:"+person);
            
        }
    }
    

    1.重写clone方法,依次调用成员变量的clone方法

        @Override
        protected Person clone() {
            try {
                Person person = (Person) super.clone();
                Child child = person.getChild().clone();
                person.setChild(child);
                return person;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    public class Test {
    
        public static void main(String[] args) {
            Person person = new Person("父亲");
            person.setChild(new Child("孩子"));
    
            //person:Person{name='父亲', child=Child{name='孩子'}}
            System.out.println("person:"+person);
    
            Person clonePerson = person.clone();
            clonePerson.getChild().setName("孩子2");
    
            //clonePerson:Person{name='父亲', child=Child{name='孩子2'}}
            System.out.println("clonePerson:"+clonePerson);
    
            //person:Person{name='父亲', child=Child{name='孩子'}}
            System.out.println("person:"+person);
    
        }
    }
    

    2.通过序列化和反序列化实现

    类实现序列化

    public class Person implements Cloneable,Serializable
    public class Child implements Cloneable, Serializable
    
        @Override
        protected Person clone() {
            ByteArrayOutputStream byteArrayOutputStream =null;
            ObjectOutputStream objectOutputStream =null;
            ByteArrayInputStream byteArrayInputStream =null;
            ObjectInputStream objectInputStream =null;
            try {
                byteArrayOutputStream = new ByteArrayOutputStream();
                objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
                objectOutputStream.writeObject(this);
    
                byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                objectInputStream = new ObjectInputStream(byteArrayInputStream);
                Person person = (Person)objectInputStream.readObject();
                return person;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    byteArrayOutputStream.close();
                    byteArrayInputStream.close();
                    objectOutputStream.close();
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    

    3.使用工具类来实现序列化和反序列化

    • BeanUtils
    • MapStruct

    相关文章

      网友评论

          本文标题:原型模式

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