单一职责原则(SRP:Single responsibility principle)又称单一功能原则,对于一个类而言,不应存在多于一个导致类变更的原因,否则类应该被拆分,也就是说一个类只负责一项职责。如果一个类承担的职责项过多,就等于把这些职责耦合起来,使其难维护,复用度低,缺乏灵活性,当需求发生变化时,一项功能职责的变动可能导致整个功能无法使用,因此在实际中开发中,我们应将类的功能职责粒度分解,其核心就是控制类的粒度大小、将对象解耦、提高其内聚性。
交通工具的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | 
 
  public class SingleResponsibility1 {     public static void main(String[] args) {         Vehicle vehicle = new Vehicle();         vehicle.run("摩托车");         vehicle.run("汽车");         vehicle.run("飞机");     }     private static class  Vehicle{         void run(String vehicle) {             System.out.println(vehicle + " 在公路上运行....");         }     } }
 
  | 
飞机本应天空中飞行,显然方式一中 Vehicle 的 run 方法中,违反了单一职责原则,根据单一职责原则改进如下:
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
   | 
 
  public class SingleResponsibility2 {     public static void main(String[] args) {         RoadVehicle roadVehicle = new RoadVehicle();         roadVehicle.run("摩托车");         roadVehicle.run("汽车");
          AirVehicle airVehicle = new AirVehicle();         airVehicle.run("飞机");
          WaterVehicle waterVehicle = new WaterVehicle();         waterVehicle.run("轮船");     }     private static class RoadVehicle {         void run(String vehicle) {             System.out.println(vehicle + "公路运行");         }     }
      private static class AirVehicle {         void run(String vehicle) {             System.out.println(vehicle + "天空运行");         }     }
      private static class WaterVehicle {         void run(String vehicle) {             System.out.println(vehicle + "水中运行");         }     } }
 
  | 
改进之后,每个交通工具类都有自己的单一职责,互不影响,遵守单一职责原则,但是这种改动花销很大,除了要根据职责将类分解为多个类,同时还要修改客户端。因此,改进如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | 
 
  public class SingleResponsibility3 {     public static void main(String[] args) {         VehicleCommon vehicleCommon  = new VehicleCommon();         vehicleCommon.runRoad("汽车");         vehicleCommon.runAir("飞机");         vehicleCommon.runWater("轮船");     }     private static class VehicleCommon {         public void runRoad(String vehicle) {             System.out.println(vehicle + " 在公路上运行....");
          }         public void runAir(String vehicle) {             System.out.println(vehicle + " 在天空上运行....");         }         public void runWater(String vehicle) {             System.out.println(vehicle + " 在水中行....");         }     }
  }
 
  | 
可以看到,这种方式没有对类进行拆分,只是增加方法,改动不大,但最终也满足实际的需求,这种改动虽然没有在类这个级别上遵守单一职责原则,但是在方法级别上,仍然是遵守单一职责原则。在实际开发中,我们可以根据实际情况决定在类级别上遵守单一职责原则,还是在方法级别上遵守单一职责原则;
附:本次演示的项目地址
https://github.com/syshlang/java-design-principle