• 利用java反射机制,子类从父类拷贝属性解决信息修改类设计的模式


    用例场景:在一个商户管理系统中,操作人员对一个已注册的商户进行修改,这就触发了一个商户修改的工作流,修改提交后,修改的商户信息和原商户信息会传递到审核人员的窗口进行审核,审核完毕后,新商户信息更新,同时旧商户信息去到历史库。
     
    数据库:我们这里有三张表——BusiInfo,BusiInfo_hist,BusiInfo_ba。BusiInfo是商户信息表存放经过注册的商户信息;BusiInfo_hist是商户信息历史表,将修改完成后的商户原信息保存到此处;BusiInfo_ba是商户信息在途表,保存并未审核通过的修改后信息,当审核通过后转移到_hist历史表,并将在途信息删除。
     
    例子:比如商户信息为a,现在修改为b,我们看看各表中的数据如何变化。
     
    修改前
    修改中
    修改后
    BusiInfo
    a
    a
    b
    BusiInfo_ba
     
    b
     
    BusiInfo_hist
     
     
    a
     
     
    好,现在我们开始编码,我们采用的是hibernate,通常的做法是每个表对应一个javabean,当信息在不同表中进行转移的时候,通常的做法是将先一个javabean中的信息一个一个getMessage(),然后再一个一个setMessage()到另一个javabean中。如果属性很多的话这是一个体力活,同时如果以后有新增属性的话,还要回来维护这个传值的方法。
     
    我们决定找到一个一劳永逸的方法来解决这类问题。这里我们用到了java继承和反射机制。
    Java代码  
    package com.mytesta;  
    /** 
     * 商户信息类,父类 
     */  
    public class BusiInfoIn {  
        public String busiId;  
        public String busiLoginname;  
        public Long number;  
        public Long getNumber() {  
            return number;  
        }  
        public void setNumber(Long number) {  
            this.number = number;  
        }  
        public String getBusiId() {  
            return busiId;  
        }  
        public void setBusiId(String busiId) {  
            this.busiId = busiId;  
        }  
        public String getBusiLoginname() {  
            return busiLoginname;  
        }  
        public void setBusiLoginname(String busiLoginname) {  
            this.busiLoginname = busiLoginname;  
        }  
    }  
    Java代码  
    package com.mytesta;  
    /** 
     * 商户历史信息类,子类,同理可建立商户在途信息类 
     * 
     */  
    public class BusiInfoIn_his extends BusiInfoIn {  
        public String deleteDate;  
      
        public String getDeleteDate() {  
            return deleteDate;  
        }  
      
        public void setDeleteDate(String deleteDate) {  
            this.deleteDate = deleteDate;  
        }  
    }  
     
    Java代码  
    package com.mytesta;  
      
    import java.lang.reflect.Field;  
    import java.lang.reflect.Method;  
      
    import junit.framework.TestCase;  
      
    public class BusiInfoTest extends TestCase {  
         public void test() throws Exception {  
             //  
             BusiInfoIn_his busiInfoIn_his=new BusiInfoIn_his();  
             busiInfoIn_his.setBusiId("1243124");  
             busiInfoIn_his.setBusiLoginname("jeffen");  
             busiInfoIn_his.setDeleteDate("2009-1-1");  
             BusiInfoIn busiInfo =new BusiInfoIn();  
             busiInfo=(BusiInfoIn)busiInfoIn_his;  
             System.out.println("子类传父类=============================");  
             System.out.println(busiInfo.getBusiId());  
             System.out.println(busiInfo.getBusiLoginname());  
               
             BusiInfoIn busiInfo2 =new BusiInfoIn();  
             busiInfo2.setBusiId("09090909");  
             busiInfo2.setBusiLoginname("runrun");  
             busiInfo2.setNumber(11L);  
             BusiInfoIn_his busiInfoIn_his2=new BusiInfoIn_his();  
             this.fatherToChild(busiInfo2, busiInfoIn_his2);  
             System.out.println("父类传子类=============================");  
             System.out.println(busiInfoIn_his2.getBusiId());  
             System.out.println(busiInfoIn_his2.getBusiLoginname());  
             System.out.println(busiInfoIn_his2.getNumber());  
             System.out.println(busiInfoIn_his2.getDeleteDate());  
               
               
         }  
         /* 
          * 将父类所有的属性COPY到子类中。 
          * 类定义中child一定要extends father; 
          * 而且child和father一定为严格javabean写法,属性为deleteDate,方法为getDeleteDate 
          */  
         private void fatherToChild (Object father,Object child)throws Exception{  
             if(!(child.getClass().getSuperclass()==father.getClass())){  
                 throw new Exception("child不是father的子类");  
             }  
             Class fatherClass= father.getClass();  
             Field ff[]= fatherClass.getDeclaredFields();  
             for(int i=0;i<ff.length;i++){  
                 Field f=ff[i];//取出每一个属性,如deleteDate  
                 Class type=f.getType();  
                 Method m=fatherClass.getMethod("get"+upperHeadChar(f.getName()));//方法getDeleteDate  
                 Object obj=m.invoke(father);//取出属性值               
                 f.set(child,obj);  
             }  
         }  
         /** 
          * 首字母大写,in:deleteDate,out:DeleteDate 
          */  
         private String upperHeadChar(String in){  
             String head=in.substring(0,1);  
             String out=head.toUpperCase()+in.substring(1,in.length());  
             return out;  
         }  
      
    }  
     我们可以看到子类比父类多了一个属性deleteDate,代表进入历史表的时间。上面的运行结果如下
    Java代码  
    子类传父类=============================  
    1243124  
    jeffen  
    父类传子类=============================  
    09090909  
    runrun  
    11  
    null  
     可以看到只要我们的持久类采用标准的javabean格式,子类从父类拷贝属性信息一步完成,而且不受以后属性增减的影响。
  • 相关阅读:
    Python学习--10 面向对象编程
    Python学习--09 模块
    Python学习--08函数式编程
    JSON的简单例子
    error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCompat.Light'.
    Failed to create the Java Virtual Machine.问题的解决
    导入项目时Loading descriptor ...
    Tomcat Server Timeouts属性的设置
    Type mismatch: cannot convert from java.sql.PreparedStatement to com.mysql.jdbc.PreparedStatement
    MySQL的Incorrect string value错误
  • 原文地址:https://www.cnblogs.com/huapox/p/3516088.html
Copyright © 2020-2023  润新知