一、前言
单一职责原则是对类来说的,即一个类应该只负责一项具体的职责.如类 A 负责两个不同职责:职责 1、职责 2.当职责 1 需求变更而改变 A 时,可能造成职责 2 执行错误,所以需要将类 A 的粒度分解为 A1、A2
单一职责原则注意事项和细节
1、降低类的复杂度,一个类只负责一项职责
2、提高类的可读性,可维护性
3、降低变更引起的风险
4、通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则,只有类中方法数量足够少,可以在方法级别保持单一职责原则
二、案例分析(以交通工具运行方式为例)
1、方式一
// 测试类
public class DesignPatternPrinciple {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("car");
vehicle.run("railway");
vehicle.run("steamer");
vehicle.run("airplane");
}
}
// 交通工具类
class Vehicle{
public void run(String vehicleType){
System.out.println(vehicleType + "在地上运行...");
}
}
// 测试结果
car在地上运行...
railway在地上运行...
steamer在地上运行...
airplane在地上运行...
方式一代码比较简单,但是我们发现一个问题, car 、railway 在地上运行时符合我们逻辑的,但是 steamer、airplane 在地上运行,这明显不符合我们的思维逻辑,它违反了单一职责,即一个类应该只完成一项具体的职责,而我们这里的 Vehicle 却完成了多项职责,所以我们尝试着改进
2、方式二
public class DesignPatternPrinciple {
public static void main(String[] args) {
RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("railway");
SeaVehicle seaVehicle = new SeaVehicle();
seaVehicle.run("steamer");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("airplane");
}
}
class RoadVehicle{
public void run(String vehicleType){
System.out.println(vehicleType + "在地上运行...");
}
}
class SeaVehicle{
public void run(String vehicleType){
System.out.println(vehicleType + "在海上运行...");
}
}
class AirVehicle{
public void run(String vehicleType){
System.out.println(vehicleType + "在空中运行...");
}
}
// 测试结果
railway在地上运行...
steamer在海上运行...
airplane在空中运行...
方式二就严格的遵循了单一职责原则,不同类型的交通工具运行方式进行类级别的拆分,每个类只负责完成自己对应的运行方式,但是呢,这里有一个缺点,我们这里类的方法很少,只有一个 run 方法,但是我们需要使用的时候创建了三个类,并且呢使用不同的交通工具的时候还创建了三次对象,这样的花销是很大的,所以我们还可以改进
3、方式三
public class DesignPatternPrinciple {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.runWithRoad("railway");
vehicle.runWithSea("steamer");
vehicle.runWithAir("airplane");
}
}
class Vehicle{
public void runWithRoad(String vehicleType){
System.out.println(vehicleType + "在地上运行...");
}
public void runWithSea(String vehicleType){
System.out.println(vehicleType + "在海上运行...");
}
public void runWithAir(String vehicleType){
System.out.println(vehicleType + "在空中运行...");
}
}
// 测试结果
railway在地上运行...
steamer在海上运行...
airplane在空中运行...
方式三虽然不是完全遵循单一职责原则,但是它却是在方法级别上遵循了单一职责原则,我们之所以这样设计是因为它这个类里面的方法很少,如果 Vehicle 类中方法比较多的情况下还采用方式三的设计原则,就会造成Vehicle 这个类里面的方法很多,设计上就会很臃肿,所以方法较多的情况下建议使用方式二