您的位置:首页 > 其它

敏捷开发1-单一职责原则

2008-04-20 00:15 148 查看
单一职责原则(The Single Responsibility Principle): 每一个类都应该只为一个理由而修改,当一个类包含其它功能时,就违反了单一职责原则。

示例
     这是一个会议管理系统。它用来管理所有参会者的信息。刚开始的时候,我们只需要记录每个参会者的ID(这是会议组织者分配的),姓名,电话和地址就行。于是,我们写了如下的代码:
     class Participant {                                                                            
       String id;                                                                                  
       String name;                                                                                
       String telNo;                                                                              
       String address;                                                                            
     }    
    
     class ConferenceSystem {                                                                      
       Participant participants[];                                                                
     }       
     接着,新的需求来了:现在每个参会者都可以让组织者帮忙预订酒店,所以我们要记录下他想预订的酒店名,入住日期,离开日期,房间类型(单人房或者双人房)。于是我们又扩充成如下的代码:    
     class Participant {                                                                            
       String id;                                                                                  
       String name;                                                                                
       String telNo;                                                                              
       String address;                                                                            
       boolean bookHotelForHim;                                                                    
       String hotelName;                                                                          
       Date checkInDate;                                                                          
       Date checkOutDate;                                                                          
       boolean isSingleRoom;                                                                      
       void setHotelBooking(String hotelName, Date checkInDate, ...) {                            
           ...                                                                                    
       }                                                                                          
     }
                                                                                     
     接着,又有一个新的需求来了:参会者可以参加不同的研讨会,所以我们要记录下参会者参加的研讨会。对于他要参加的每一场研讨会,我们还要记录下他的登记时间,同时他还需要什么翻译设备。于是代码又扩充成:
     class Participant {                                                                            
       String id;
       String name;
       String telNo;
       String address;
       boolean bookHotelForHim;
       String hotelName;
       Date checkInDate;
       Date checkOutDate;
       boolean isSingleRoom;
       String idOfSeminarsRegistered[];
       Date seminarRegistrationDates[];
       boolean needSIDeviceForEachSeminar[];
       void setHotelBooking(String hotelName, Date checkInDate, ...) {
           ...
       }    
       void registerForSeminar(String seminarId, Date regDate, boolean needSIDevice) {
           //将seminarId加到idOfSeminarsRegistered
           //将regDate加到seminarRegistrationDates
           //将needSIDevice加到needSIDeviceForEachSeminar.
       }    
       boolean isRegisteredForSeminar(String seminarId) {
           ...
       }    
       Date getSeminarRegistrationDate(String seminarId) {
           ...
       }    
       boolean needSIDeviceForSeminar(String seminarId) {
           ...
       }    
       String [] getAllSeminarsRegistered() {
           return idOfSeminarsRegistered;
       }    
     }
     代码开始肿胀起来了
     请注意,这已经是我们第二次扩充Participant这个类了。每扩充一次,它就包含了更多的代码(实例变量和方法)及更多的功能。本来它只有4个属性。现在已经是12个了!此外,这个类要处理的业务逻辑也极大的增加了。本来它只需要处理参会者的基本信息(姓名,地址等等),现在它还要包含酒店,酒店预订,研讨会和翻译设备等等的逻辑。如果以后新的需求又来了,我们又要扩充Participant这个类,到时候,这个类要复杂庞大成什么样子!
     所以我们得修整这个类了!
     那怎么修整Participant这个类呢?怎么让它一直保持在第一天那样的简洁度?在回答这两个问题之前,我们先来考虑一下另一个需要优先回答的问题:给你一个
4000
类,你怎么认定它需要修整?
怎么判断一个类需要修整
     要判断一个类是否需要修整,一个比较主观的方法是:当在读一个类的代码时,看看我们会不会觉得这个类“太长了”,“太复杂了”,或者讲的概念“太多了”?如果会这样觉得的话,我们就认定,这个类需要修整。
     另外一个比较简单而且客观的方法是:当发现我们已经在第二次或者第三次扩充这个类的时候,我们认定这个类要修整了。这是一个比较”懒惰,被动”的方法,但却很有效。
     现在让我们看一下怎么修整Participant这个类吧。
     抽取出有关酒店预订的功能
     首先,先来考虑一下怎么抽取出酒店预订的功能。一个可行的方案是:
class Participant {                                                                            
       String id;                                                                                  
       String name;                                                                                
       String telNo;                                                                              
       String address;                                                                            
     }      
    
     class HotelBooking {                                                                          
       String participantId;                                                                      
       String hotelName;                                                                          
       Date checkInDate;                                                                          
       Date checkOutDate;                                                                          
       boolean isSingleRoom;                                                                      
     }    
    
     class HotelBookings {                                                                          
       HotelBooking hotelBookings[];                                                              
       void addBooking(HotelBooking booking) {                                                    
           ...                                                                                    
       }                                                                                          
     }        
    
     class ConferenceSystem {                                                                      
       Participant participants[];                                                                
       HotelBookings hotelBookings;                                                                
     }

                                                                                            
     现在,Participant这个类就一点都不知道酒店预订的存在。当然,我们不一定要用数组来存放酒店预订情况。比如,我们可以用Map:
   class Participant {                                                                            
       String id;                                                                                  
       String name;                                                                                
       String telNo;                                                                              
       String address;                                                                            
     }                                                                                              

     class HotelBooking {
       String participantId;
       String hotelName;
       Date checkInDate;
       Date checkOutDate;
       boolean isSingleRoom;
     }    
    
     class HotelBookings {
       HashMap mapFromPartIdToHotelBooking;
       //必须提供参会者id
       void addBooking(String participantId, HotelBooking booking) {
           ...
       }    
     }      

     class ConferenceSystem {
       Participant participants[];
       HotelBookings hotelBookings;
     }
     这样的方案优点是Participant一点都不知道HotelBooking的存在,Participant不依赖于HotelBooking。
     还有另一个可行的方案是:
     class Participant {
       String id;
       String name;
       String telNo;
       String address;
       HotelBooking hotelBooking;
     }      
    
     class HotelBooking {
       String hotelName;
       Date checkInDate;
       Date checkOutDate;
       boolean isSingleRoom;
     }    
    
     class ConferenceSystem {
       Participant participants[];
     }    

  
     注意到,在这种方案里面,Participant这个类还是要知道HotelBooking的存在,也就是说,Participant还是要知道有酒店预订这回事。只是具体酒店预订是怎么做的,这些真正的功能是放在HotelBooking这个里面实现的。因为每个Participant都直接引用了本人的酒店预订情况,所以可以直接找到他的酒店预订情况。而代价就是,Pariticipant还是要知道酒店预订的概念。从类的关系来讲,Pariticipant还要依赖HotelBooking这个类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息