天天看点

单一职责原则单一职责原则(Single Responsibility Principle)

单一职责原则(Single Responsibility Principle)

参考书籍:Spring5核心原理与30个类手写实战
  • 基本概述:是指不要存在多于一个导致类变更的原因。假如我们有一个类负责两项职责,一旦发生需求变更需要修改其中一项职责的逻辑代码,有可能导致另一项职责的功能发生故障。这样一来这个类就存在两项导致类变更的原因。解决这个问题的办法就是将两个职责使用两个类来实现,进行解耦。后期的需求变更维护时互不影响。单一职责原则的好处是可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低需求变更时引起的风险。总体来说,就是一个类、接口或者方法只负责一项职责(具体使用根据业务拆分)。
  • 从类的角度看单一职责原则
/**
 * 课程类
 * 功能职责一:直播课不能快进和快退
 * 功能职责二:录播课可以反复的任意观看
 * 普通写法
 */
public class Course {
    public void study(String courseName) {
        if ("直播课".equals(courseName)) {
            System.out.println(courseName + "不能快进");
        } else {
            System.out.println(courseName + "可以反复回看");
        }
    }
}
/**
 * 调用代码检验结果
 */
public class Check {
    public static void main(String[] args) {
        Course course = new Course();
        course.study("直播课");
        course.study("录播课");
    }
}
           
  • 输出结果:
直播课不能快进
录播课可以反复回看
           
  • 假如此时需求发生变更,课程需要加密,两种课程的加密逻辑不同,必须修改代码,而修改代码的逻辑势必会相互影响,容易带来不可控的风险。我们需要对原来的代码进行解耦。
/**
 * 直播课程
 */
public class LiveCourse {
    public void study(String courseName) {
        System.out.println(courseName + "不能快进看");
    }
}
/**
 * 录播课程
 */
public class ReplayCourse {
    public void study(String courseName) {
        System.out.println(courseName + "可以反复回看");
    }
}
/**
 * 调用代码检验结果
 */
public class Check {
    public static void main(String[] args) {
        LiveCourse liveCourse = new LiveCourse();
        liveCourse.study("直播课");
        ReplayCourse replayCourse = new ReplayCourse();
        replayCourse.study("录播课");
    }
}
           
  • 输出结果:
直播课不能快进看
录播课可以反复回看
           
  • 从接口的角度看单一职责原则
  • 假如需求发生更改,课程要做权限功能。没有付费的学员只能获取课程基本信息,已经付费的学员可以获得视频流进行学习即拥有学习权限。
/**
 * 课程顶层接口,包含课程的所有功能
 * 获取课程名称
 * 获取视频流
 * 学习课程
 */
public interface ICourse {
    String getCourseName();

    byte[] getCourseVideo();

    void studyCourse();
}
           
  • 使用单一职责原则根据业务拆分接口,此时课程至少要有两项职责,一项是展示课程信息的职责,另一项是管理课程的职责。
/**
 * 展示课程信息
 * 获取课程名称
 * 获取视频流
 */
public interface ICourseInfo {
    String getCourseName();

    byte[] getCourseVideo();
}
/**
 * 管理课程
 * 学习课程
 */
public interface ICourseManager {
    void studyCourse();
}
           
  • 从方法的角度看单一职责原则
  • 假如需求变更需要修改学员信息
/**
 * 修改用户信息
 */
public class UserInfo {
    public void modify(String userName, String address, String ...info){
        userName = "Tom";
        address = "ShangHai";
    }
}
           
  • modify方法负责修改学员的全部信息,使得该方法承担多项职责,我们需要把方法进行拆分。
/**
 * 修改用户信息
 */
public class UserInfo {
    public void modifyUserName(String userName) {
        userName = "Tom";
    }

    public void modifyAddress(String address) {
        address = "ShangHai";
    }
}
           
  • 总的来说,我们在编写代码的时候尽量遵守单一职责原则,在类、接口、方法层面我们需要根据具体业务进行拆分,目的都是为了解耦合从而降低类的复杂度,提高类的可读性,提高系统的可维护性,降低需求变更时引起的风险。