`
Wingel
  • 浏览: 117536 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

阅读更多
第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的)。


继承了一些不合适(或者没用的)的功能
下面的内容请到附件里查看。
分享到:
评论

相关推荐

    敏捷开发的必要技巧

    第5章:慎用继承 在面向对象编程中,继承是一种重要的机制,但过度依赖或误用可能导致复杂性增加。本章讨论了何时应该使用继承,以及如何合理地利用接口和组合来替代继承,以减少代码耦合,提高模块化和可扩展性。这...

    敏捷软件开发的必要技巧

    #### 六、慎用继承 **1. 继承的滥用问题** - 过度使用继承可能导致类层次过于复杂。 - 继承层次结构的变动会影响所有子类。 **2. 使用继承的原则** - **遵循Liskov替换原则**:子类应该能够替换其父类。 - **...

    敏捷开发的必要技巧(完整版)

    #### 六、慎用继承 **继承的不当使用** - 过度依赖继承可能导致类之间的耦合度过高。 - 继承层次过深可能会增加系统的复杂度。 **正确使用继承的建议** 1. **优先考虑组合而非继承**:通过组合不同的类来达到...

    敏捷软件开发的必要技巧完整版

    #### 六、慎用继承 **1. 继承的局限性** - **过度继承可能导致代码耦合度过高**:过多的继承关系可能使代码变得难以理解和维护。 - **违反单一职责原则**:一个类如果承担太多的责任,可能会导致继承结构过于复杂。 ...

Global site tag (gtag.js) - Google Analytics