敏捷开发的必要技巧5:慎用继承

下载地址 


http://www.blogjava.net/Files/Wingel/第5章慎用继承.rar

http://wingel.javaeye.com/topics/download/81eb4c8a-e19f-48a3-bcf9-1256053a1d79

下面是摘录的片段:


第5章 慎用继承

示例

   这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表Participants,里面的每条记录表示一个参会者。因为经常会发生 用户误删掉某个参会者的信息。所以现在,用户删除时,并不会真的删除那参会者的信息,而只是将该记录的删除标记设为true。24小时以后,系统会自动将 这条记录删除。但是在这24小时以内,如果用户改变主意了,系统还可以将这条记录还原,将删除标记设置为false。

  请认真的读下面的代码:

    public class DBTable {                                                                        
       protected Connection conn;                                                                 
       protected tableName;                                                                       
       public DBTable(String tableName) {                                                         
           this.tableName = tableName;                                                            
           this.conn = ...;                                                                       
       }                                                                                          
       public void clear() {                                                                      
           PreparedStatement st = conn.prepareStatement("DELETE FROM "+tableName);                
           try {                                                                                  
               st.executeUpdate();                                                                
           }finally{                                                                              
               st.close();                                                                        
           }                                                                                      
       }                                                                                          
       public int getCount() {                                                                    
           PreparedStatement st = conn.prepareStatement("SELECT COUNT(*) FROM"+tableName);                                                                                 
           try {                                                                                  
               ResultSet rs = st.executeQuery();                                                  
               rs.next();                                                                         
               return rs.getInt(1);                                                               
           }finally{                                                                              
               st.close();                                                                        
           }                                                                                      
       }                                                                                          
    }                              
   
    public class ParticipantsInDB extends DBTable {                                               
       public ParticipantsInDB() {                                                                
           super("participants");                                                                 
       }                                                                                          
       public void addParticipant(Participant part) {                                             
           ...                                                                                    
       }                                                                                          

       public void deleteParticipant(String participantId) {
           setDeleteFlag(participantId, true);
       }                     
       public void restoreParticipant(String participantId) {
           setDeleteFlag(participantId, false);
       }                     
       private void setDeleteFlag(String participantId, boolean b) {
           ...               
       }                     
       public void reallyDelete() {
           PreparedStatement st = conn.prepareStatement(
                             "DELETE FROM "+
                             tableName+
                             " WHERE deleteFlag=true");
           try {             
               st.executeUpdate();
           }finally{         
               st.close();   
           }                 
       }                     
       public int countParticipants() {
           PreparedStatement st = conn.prepareStatement(
                             "SELECT COUNT(*) FROM "+
                             tableName+
                             " WHERE deleteFlag=false");
           try {             
               ResultSet rs = st.executeQuery();
               rs.next();    
               return rs.getInt(1);
           }finally{         
               st.close();   
           }                 
       }                     
    }                        

  注意到,countParticipants这个方法只计算那些deleteFlags为false的记录。也就是,被删除的那些参会者不被计算在内。

  上面的代码看起来还不错,但却有一个很严重的问题。什么问题?先看看下面的代码:

    ParticipantsInDB partsInDB = ...;
    Participant kent = new Participant(...);
    Participant paul = new Participant(...);
    partsInDB.clear();       
    partsInDB.addParticipant(kent);
    partsInDB.addParticipant(paul);
    partsInDB.deleteParticipant(kent.getId());
    System.out.println("There are "+partsInDB.getCount()+ "participants");

   最后一行代码,会打印出"There are 1 participants"这样信息,对不?错!它打印的是"There are 2 participants"!因为最后一行调用的是DBTable里面的这个方法getCount,而不是ParticipantsInDB的 countParticipants。getCount一点都不知道删除标记这回事,它只是简单的计算记录数量,并不知道要计算那些真正有效的参会者(就 是删除标记为false的)。


继承了一些不合适(或者没用的)的功能

内容较长,具体的内容在上面的下载链接里面的pdf文件里。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值