敏捷开发中要慎用继承(1)

发表于:2007-06-12来源:作者:点击数: 标签:
示例 这是一个会议管理系统。用来管理各种各样的会议参与者信息。 数据库 里面有个表Particip ant s,里面的每条记录表示一个参会者。因为经常会发生用户误删掉某个参会者的信息。所以现在,用户删除时,并不会真的删除那参会者的信息,而只是将该记录的删除

示例

这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表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的)。
 

共4页: 1 [2] [3] [4] 下一页

原文转自:http://www.ltesting.net