zoukankan      html  css  js  c++  java
  • 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);
        }
    
    }
  • 相关阅读:
    链表的Java实现
    java知识点
    java知识点
    Android基础知识总结
    Android基础知识总结
    路由知识之ip route 命令中的疑惑
    Integer与int的种种比较
    求二叉树的宽度C语言版
    求二叉树的宽度C语言版
    二叉树的建立与递归遍历C语言版
  • 原文地址:https://www.cnblogs.com/mahongbiao/p/8625915.html
Copyright © 2011-2022 走看看