• 设计模式三 原型模式


    0、 基本定义

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

    implement Cloneable

    不支持 final

    BeanUtils copy 有使用反射实现

    浅拷贝:字段是值类型,逐位复制;字段是引用类型,复制引用但不复制引用对象。

    深拷贝:复制引用对象, 可通过 序列化方式实现。

    1、代码参考

    Resume.java

    public class Resume implements Cloneable, Serializable{
    
        private String name;
        private String sex;
        private String age;
        private String timeArea;
        private String company;
    
        private WorkExperience work;
    
        public Resume(String name) {
            this.name = name;
            work = new WorkExperience();
        }
    
        public void setPersonalInfo(String sex, String age) {
            this.sex = sex;
            this.age = age;
        }
    
        public void setWorkExperience(String timeArea, String company) {
            this.timeArea = timeArea;
            this.company = company;
    
            //深 拷贝
            work.setCompany(company);
            work.setWorkDate(timeArea);
        }
    
        public void display() {
            System.out.println(String.join(" ", name, sex, age));
            System.out.println("工作经历:" + String.join(" ", timeArea, company                                                                                                 ));
            System.out.println("workExperience:" + String.join(" ", work.getCompany(), work.getWorkDate()                                                                                                 ));
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
    //深拷贝 1
    public Object deepClone() throws IOException, ClassNotFoundException { // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); Resume o = (Resume) ois.readObject(); return o; }

      //深拷贝 2 - 常规
    public Object deepClone2() throws Exception { Resume clone = (Resume) super.clone(); clone.work = (WorkExperience) this.work.clone(); return clone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getTimeArea() { return timeArea; } public void setTimeArea(String timeArea) { this.timeArea = timeArea; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } }

     WorkExperience.java

    public class WorkExperience implements Serializable,Cloneable{
    
        private String workDate;
        private String company;
    
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        public String getWorkDate() {
            return workDate;
        }
    
        public void setWorkDate(String workDate) {
            this.workDate = workDate;
        }
    
        public String getCompany() {
            return company;
        }
    
        public void setCompany(String company) {
            this.company = company;
        }
    }

    Test.java

    public class ResumeTest {
    
        public static void main(String[] args) throws Exception {
    
            //浅复制
            Resume resume = new Resume("fred");
            resume.setPersonalInfo("male", "29");
            resume.setWorkExperience("1990-2008", "company A");
    
    //        Resume b = (Resume) resume.deepClone();
            Resume b = (Resume) resume.deepClone2();
    //        Resume b = (Resume) resume.clone();
    
            System.out.println("resume == b?" + (resume == b));
            System.out.println("resume.getClass() == b.getClass()?" + (resume.getClass() == b.getClass()));
            b.setWorkExperience("2000-2015"," tongdun");
    
            Resume c = (Resume) resume.clone();
            c.setPersonalInfo("male", "30");
    
            System.out.println("===============");
            resume.display();
            System.out.println("===============");
            b.display();
            System.out.println("===============");
            c.display();
    
            System.out.println("=====deep clone ====");
    
        }
    }

    结果:

    
    

    ===============
    fred male 29
    工作经历:1990-2008 company A
    workExperience: tongdun 2000-2015
    ===============
    fred male 29
    工作经历:2000-2015 tongdun
    workExperience: tongdun 2000-2015
    ===============
    fred male 30
    工作经历:1990-2008 company A
    workExperience: tongdun 2000-2015


    ======deep clone========= fred male 29 工作经历:1990-2008 company A workExperience:company A 1990-2008 =============== fred male 29 工作经历:2000-2015 tongdun workExperience: tongdun 2000-2015 //使用深拷贝后 =============== fred male 30 工作经历:1990-2008 company A workExperience:company A 1990-2008 =====deep clone ====

    2 后续 

    2.1 优点:

    》原型模式是在内存 二进制流的拷贝,比new 性能要好

    》逃避构造函数的约束

    双刃剑

    2.2 使用场景

     》资源优化场景

    - 类初始化需要消耗很多的资源

    》性能和安全要求的场景

    - 通过new长生一个对象需要非常 繁琐的数据准备或访问权限

    》一个对象多个修改者的场景

    =========================

     persistence 2.  这块语言描述总结不是很好,源于自己也还有些模糊, 待续完善。。。。。

    =========================

    参考资料:

    咕泡学院- 这块讲的一般

    《大话设计模式》

    《设计模式之蝉》

  • 相关阅读:
    springboot+websocket 归纳收集
    flask-admin 快速打造博客 系列一
    Flask-sqlalchemy 语法总结
    python 小问题收集
    pyenv+virtual 笔记
    flask_admin 笔记七 扩展功能
    Flask_admin 笔记六 modelView的内置方法
    spring boot 项目中 maven打第三方lib包时遇到的问题以及解决方法
    java 字符串压缩长度并解压
    highcharts中放aqi及6要素,再加上气象5要素的图
  • 原文地址:https://www.cnblogs.com/idea-persistence/p/9533254.html
Copyright © 2020-2023  润新知