1. 目标精通--用java写设计模式:单一职责原则

本文深入解析单一职责原则,探讨其在软件设计中的应用与实践,包括原则定义、职责扩散概念及解决方案,通过代码案例展示了如何遵守类和方法的单一职责原则。

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 分析
  • 在方法足够少,逻辑足够简单的类中,如果发生职责扩散,可以允许不遵守的单一职责原则,但是一定到遵守方法的单一职责原则
  • 一个方法,只做一件事,在这里的体现就是,一个方法,只跑一个领域的交通工具

4. 下一章:接口隔离原则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值