• Java设计模式(五)Prototype原型模式


    一、场景描述

    创建型模式中,从工厂方法模式,抽象工厂模式,到建造者模式,再到原型模式,我的理解是,创建对象的方式逐步从编码实现转向内存对象处理。

    例如,在“仪器数据采集器”的子类/对象“PDF文件数据采集器”和“Excel文件数据采集器”的创建过程中,

    工厂模式下定义各子类,并由(抽象)工厂类Factory创建,因此各子类可在类定义中定义各自的属性;

    建造者模式下,通过不同的创建者类Builder创建不同的子对象,此时不再定义子类;

    而原型模式下,则完全由调用者基于父对象克隆创建子对象,不在针对子对象创建类或者其相关的工厂、建造者类。

    三种模式对应于不同的场景,实际操作时,根据场景合理选择模式。

    原型模式下,基于原型类对象,克隆创建新对象,因此为原型类对象赋予的属性值在新对象中可直接使用,免去了重复赋值;

    例如仪器数据采集器的共同初始化工作可在原型类对象中完成,随后将其克隆出PDF文件数据采集器对象和Excel文件数据采集器对象,并为两对象属性做后续的扩展,免去了公共属性的初始化工作;

    克隆操作在内存中完成,由于对象类型的属性值存储为引用,因此克隆分浅克隆和深克隆,通过Serializable接口实现深克隆。

    二、示例代码

    原型类:

    package lims.designpatterndemo.prototypedemo;
    
    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 EquipmentDataCapture implements Cloneable, Serializable {
        private String filePath = "file path";
        private String equipmentData = "file content";
    
        //
        public String getFilePath() {
            return this.filePath;
        }
    
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }
    
        public String getEquipmentData() {
            return this.equipmentData;
        }
    
        public void setEquipmentData(String equipmentData) {
            this.equipmentData = equipmentData;
        }
    
        //
        private static final long serialVersionUID = 1L;
        private SerializableObject obj;
    
        //
        public SerializableObject getObj() {
            return obj;
        }
    
        public void setObj(SerializableObject obj) {
            this.obj = obj;
        }
        //
        public EquipmentDataCapture getEquipmentDataCapture() throws CloneNotSupportedException {  
            EquipmentDataCapture capture = (EquipmentDataCapture) super.clone();  
            return capture;  
        }  
    //    public EquipmentDataCapture getPdfFileCapture() throws CloneNotSupportedException {  
    //        EquipmentDataCapture capture = (EquipmentDataCapture) super.clone(); 
    //        capture.setEquipmentData("pdf file content");
    //        return capture;  
    //    }  
    //    public EquipmentDataCapture getExcelFileCapture() throws CloneNotSupportedException {  
    //        EquipmentDataCapture capture = (EquipmentDataCapture) super.clone(); 
    //        capture.setEquipmentData("excel file content");
    //        return capture;  
    //    }  
        /* 深复制 */  
        public EquipmentDataCapture newEquipmentDataCapture() 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);  
            return (EquipmentDataCapture)ois.readObject();  
        }  
    }
    
    class SerializableObject implements Serializable {
        private static final long serialVersionUID = 1L;
    }

    调用端:

    package lims.designpatterndemo.prototypedemo;
    
    public class PrototypeDemo {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            EquipmentDataCapture edc = new EquipmentDataCapture();
            EquipmentDataCapture capture = null;
    //        capture = edc.getPdfFileCapture();
    //        capture = edc.getExcelFileCapture();
            capture = edc.getEquipmentDataCapture();
            capture.setEquipmentData("equipment data file content");
            String fileContent = capture.getEquipmentData();
            System.out.println(fileContent);
        }
    
    }
  • 相关阅读:
    es6 常用方法
    vue HTTP 请求(vue-resource)
    vue 常用语法糖
    js中slice,SubString和SubStr的区别
    浅谈JavaScript中forEach与each
    vue 新版本 webpack 代理 跨域设置
    js 动态添加class封装(es6语法)
    jsonp promise 封装
    location.origin兼容IE
    给zTree的treeNode添加class
  • 原文地址:https://www.cnblogs.com/mahongbiao/p/8625915.html
Copyright © 2020-2023  润新知