单一职责原则(Single Responsibility Principle)
引言
道生一,一生二,二生三,三生万物。正所谓,大道至简,大音希声。
定义
单一职责原则就是将不同的职责分离到单独的类,使得有且仅有一个原因引起类的变更。
应用
应用场景1
这里我们以用户管理为例,对用户的管理包括对用户信息的管理(业务对象)和对用户行为的管理(业务逻辑)。根据单一职责原则,可以将用户行为和用户信息两个职责分别作为接口,最终则由另一个操作类来实现两个接口定义的操作。这样,管理者能够只需要通过接口来对用户进行管理,并且使得两个职责分离,一个职责发生变动,不会影响另一个职责。
第一步,创建业务对象接口
提供操作用户信息的接口
1 2 3 4 5 6 7 8 9 10 11 12
   | 
 
  public interface IUserBO {     void setUserId(String userId);     String getUserId();     void setPasswd(String passwd);     String getPasswd();     void setUserName(String userName);     String getUserName(); }
 
 
  | 
 
第二步,创建业务逻辑接口
提供操作用户行为的接口
1 2 3 4 5 6 7 8 9 10 11
   | 
 
  public interface IUserBIZ {     boolean changePasswd();     boolean deleteUser(IUserBO userBO);     boolean mapUser(IUserBO userBO);     boolean addOrg(IUserBO userBO , int orgID);     boolean addRole(IUserBO userBO , int orgID); }
 
 
  | 
 
第三步,创建用户信息类
实现用户信息接口和用户行为接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
   | 
 
  public class UserInfo implements IUserBO , IUserBIZ {     private String userId ;     private String passwd ;     private String userName ;
      public UserInfo() {     }
      public UserInfo(String userId, String passwd, String userName) {         this.userId = userId;         this.passwd = passwd;         this.userName = userName;     }
      public boolean changePasswd() {         System.out.println("改变密码");         return false;     }
      public boolean deleteUser(IUserBO userBO) {         System.out.println("删除用户");         return false;     }
      public boolean mapUser(IUserBO userBO) {         return false;     }
      public boolean addOrg(IUserBO userBO, int orgID) {         return false;     }
      public boolean addRole(IUserBO userBO, int orgID) {         return false;     }
      public void setUserId(String userId) {         this.userId = userId ;     }
      public String getUserId() {         return userId ;     }
      public void setPasswd(String passwd) {         this.passwd = passwd ;     }
      public String getPasswd() {         return passwd ;     }
      public void setUserName(String userName) {         this.userName = userName ;     }
      public String getUserName() {         return userName ;     }
      @Override     public String toString() {         return "UserInfo{" +                 "userId='" + userId + '\'' +                 ", passwd='" + passwd + '\'' +                 ", userName='" + userName + '\'' +                 '}';     } }
 
 
  | 
 
第四步,测试
通过多态,只需要创建一个对象,就能被用于多种用途
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
   | import org.junit.Test;
  public class test {     @Test     public void test(){         
 
 
                   IUserBIZ userInfo = new UserInfo();                  IUserBO userBO = (IUserBO)userInfo ;                  userBO.setPasswd("123");         userBO.setUserId("1");         userBO.setUserName("name");         System.out.println(userBO);
                   IUserBIZ userBIZ = (IUserBIZ)userInfo ;                  userBIZ.deleteUser(userBO);         System.out.println(userBIZ);
      } }
 
   | 
 
结果
1 2 3
   | UserInfo{userId='1', passwd='123', userName='name'} 删除用户 UserInfo{userId='1', passwd='123', userName='name'}
  | 
 
应用场景2
电话通话的时候有4个过程发生:拨号,通话,回应,挂机。
分析
电话通话包括了两个职责:协议管理和数据传送。
我们可以将这两个职责抽象为两个接口,让一个手机类来实现。这样就能让这两个职责变得通用,手机类只需要实现自己想要的传输协议和数据传送方式就行。传输协议和传送方式这两个职责任意一个改变都不会影响到另一个职责,这使得代码改动变得更小。
第一步,创建业务对象
1 2 3 4 5 6 7 8
   | 
 
  public interface IConnectionManager {     void dial(String phoneNumber);     void hangup(); }
 
 
  | 
 
第二步,创建业务逻辑
1 2 3 4 5 6 7
   | 
 
  public interface IDataTransfer {     void DataTransfer(IConnectionManager cm); }
 
 
  | 
 
第三步,创建手机类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | 
 
  public class Phone implements IConnectionManager , IDataTransfer {     private String phoneNumber ;
      public String getPhoneNumber() {         return phoneNumber;     }
      public void setPhoneNumber(String phoneNumber) {         this.phoneNumber = phoneNumber;     }
      public void dial(String phoneNumber) {         System.out.println("接电话");     }
      public void hangup() {         System.out.println("挂断电话");     }
      public void DataTransfer(IConnectionManager cm) {         cm.dial(phoneNumber);         System.out.println("通话");         cm.hangup();     } }
 
 
  | 
 
第四步,测试
1 2 3 4 5 6 7 8 9 10
   | @Test    public void test2(){                IConnectionManager phone = new Phone();                IDataTransfer dt = (IDataTransfer)phone ;        IConnectionManager cm = (IConnectionManager)phone ;                dt.DataTransfer(cm);    }
   | 
 
##### 第五步,结果
单一职责的好处
- 类的复杂性降低,实现什么职责都有清晰明确的定义
 
- 复杂性降低,使得更具可读性。
 
- 可读性提高,使得类更容易维护。
 
- 类的变更引起的风险降低,这对系统的扩展性,维护性都有非常大的帮助。
 
单一职责的注意点
- 单一职责中的职责没有一个量化的标准,其最难划分。
 
- 单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。
 
- 对于单一职责原则,接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
 
自言自语
一天又过去了,希望明天不下雨…