文章目录
1、什么是单一职责原则
- 字面理解:一个类只担任一个职责
- 对类来说: 要么是一个用户类,要么是一个订单类,两个职责不同的类不要写在一起
- 举例: 在开发中,我们在经常会创建操作数据的Dao类,如果在数据库表中有user表和order表,那我们就需要创建一个userDao与一个orderDao,两个dao分别用来操作不同的表业务,不要将两个不同的业务写在一个类中
- 对于方法来说: 一个类中有很多的行为,也就是方法,那么我们就要保证一个方法只做一件事,最后将每个方法组合起来使用,不要把一大片的做了很多事的逻辑写在一个方法里,将每一件事进行细粒度的划分
- 作用:
- 降低类的复杂度,一个类只负责一项职责
- 提高类的可读性,可维护
- 降低变更引起的风险
- 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违 反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则
2. 单一职责原则的认识
- PS: 这一段参考于: https://www.cnblogs.com/yanggb/p/10922079.html
- 单一职责原则看起来很简单,就跟常识一样,基本上是个程序员都知道该怎么做,但是我们有时候还是会因为职责扩散的问题违背这一原则
- 职责扩散: 指的就是因为某种原因,职责P1被分化为粒度更细的职责P1和P2。下面会用代码举例
- 违背原则: 假设我在A1类中调用了P1类,后来因为需求变更,P1的职责扩散了,划分为了P1与P2。那我是不是为了遵守单一职责原则,再创建一个A2类,让A1与A2分别负责P1与P2呢?如果程序已经完成了,这样做的话开销就会太大了,因为P1扩散影响到了A1,如果A1扩散是否会影响到其他的类呢?所以简单的修改P1类,让他负责两个职责,也是可以的,虽然会违背单一原则。违背单一原则,只在简单的类,简单的代码中建议使用,如果业务复杂,最好还是遵守单一职责原则。
- 适当地违背单一职责原则有时候反而能提高开发效率,因此设计原则还是要按照实际需求来选择使用的。
3. 代码案例
3.1 一个正常的代码
public class SingleResponsibility1 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("汽车");
}
}
/**
* 交通工具类
*/
class Vehicle {
/**
* 交通工具运行的方法
*
* @param vehicleName
*/
public void run(String vehicleName) {
System.out.println(vehicleName + "在公路上行驶");
}
}
3.1.1执行结果
汽车在公路上行驶
3.1.2 分析
- 我们可以看到,这是一个很正常的类,调用了交通工具类的run方法,传入一个汽车,打印出来汽车在公路上行驶。但是如果发生了职责扩散呢?
3.2 职责扩散
- 指的就是因为某种原因,职责P1被分化为粒度更细的职责P1和P2
public class SingleResponsibility1 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("汽车");
vehicle.run("飞机"); //新增飞机运行
vehicle.run("船"); //新增船运行
}
}
/**
* 交通工具类
*/
class Vehicle {
/**
* 交通工具运行的方法
*
* @param vehicleName
*/
public void run(String vehicleName) {
System.out.println(vehicleName + "在公路上行驶");
}
}
3.2.1 执行结果
汽车在公路上行驶
飞机在公路上行驶
船在公路上行驶
3.2.2 分析
- 很明显,在我们传入飞机跟船之后,程序就不正常了。飞机跟船是不能再公路上行驶的。
- 现在这个方法不仅仅要跑公路上的,还要跑水里跟天上的,这就是职责扩散。
3.2.3 解决方案1:遵守类的单一职责原则
public class SingleResponsibility1 {
public static void main(String[] args) {
LandVehicle landVehicle = new LandVehicle();
landVehicle.run("汽车");
SkyVehicle skyVehicle = new SkyVehicle();
skyVehicle.run("飞机");
WaterVehicle waterVehicle = new WaterVehicle();
waterVehicle.run("船");
}
}
/**
* 地上跑的
*/
class LandVehicle {
/**
* 交通工具运行的方法
*
* @param vehicleName
*/
public void run(String vehicleName) {
System.out.println(vehicleName + "在公路上行驶");
}
}
/**
* 天上飞的
*/
class SkyVehicle {
/**
* 交通工具运行的方法
*
* @param vehicleName
*/
public void run(String vehicleName) {
System.out.println(vehicleName + "在天上飞");
}
}
/**
* 水里游的
*/
class WaterVehicle {
/**
* 交通工具运行的方法
*
* @param vehicleName
*/
public void run(String vehicleName) {
System.out.println(vehicleName + "在水里游");
}
}
3.2.4 执行结果
汽车在公路上行驶
飞机在天上飞
船在水里游
3.2.5 分析
- 使用类的单一职责原则,将交通工具通过天上、地下、水里分为三个类,每个类负责处理各自领域的交通工具,实现一个类只负责一个职责
- 优点: 降低类的复杂度、提高可维护性、修改一个类中的业务不会影响到其他的类
- 缺点: 这么简单的逻辑与方法却要分为三个类,这样做的开销就太大了,所以我们在方法很少的类中允许违背类的单一原则,但是要遵守方法的单一职责原则
3.2.6 解决方案2:遵守方法的单一职责原则
public class SingleResponsibility1 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.runLang("汽车");
vehicle.runSky("飞机");
vehicle.runWater("船");
}
}
/**
* 交通工具
*/
class Vehicle {
public void runLang(String vehicleName) {
System.out.println(vehicleName + "在公路上行驶");
}
public void runSky(String vehicleName){
System.out.println(vehicleName + "在天上飞");
}
public void runWater(String vehicleName){
System.out.println(vehicleName + "在水里游");
}
}
3.2.7 分析
- 在方法足够少,逻辑足够简单的类中,如果发生职责扩散,可以允许不遵守类的单一职责原则,但是一定到遵守方法的单一职责原则
- 一个方法,只做一件事,在这里的体现就是,一个方法,只跑一个领域的交通工具
本文深入解析单一职责原则,探讨其在软件设计中的应用与实践,包括原则定义、职责扩散概念及解决方案,通过代码案例展示了如何遵守类和方法的单一职责原则。


被折叠的 条评论
为什么被折叠?



