代码设计原则(三)--单一职责原则

单一职责原则(Simple Responsibility Pinciple,SRP)

​ 是指不要存在多于一个导致类变更的原因

​ 假设我们有一个 Class 负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能会导致另一个职责的功能发生故障。这样一来,这个 Class 存在两个导致类变更的原因。如何解决这个问题呢?

​ 我们就要给两个职责分别用两个 Class 来实现,进行解耦。后期需求变更维护互不影响。这样的设计, 可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。

总体来说就是一个 Class/Interface/Method 只负责一项职责。

一、一个类中负责多个职能

  • 一个类实现多种方法

    public class Course {
        public void study(String courseName) {
            if ("直播课".equals(courseName)) {
                System.out.println("不能快进");
            } else {
                System.out.println("可以任意的来回播放");
            }
        }
    }
    //mian方法
    public class Run {
        public static void main(String[] args) {
            Course course = new Course();
            course.study("直播课");
            course.study("录播课");
        }
    }
    
  • Course 类承担了两种处理逻辑。假如,现在要对课程进行加密,那么直播课和录播课的加密逻辑都不一样,必须要修改代码。而修改代码逻辑势必会相互影响容易造成不可控的风险。我们对职责进行分离解耦,来看代码,分别创建两个类 ReplayCourse 和 LiveCourse:

    public class LiveCourse {
        public void study(String courseName) {
            System.out.println(courseName + "不能快进看");
        }
    }
    
    public class ReplayCourse {
        public void study(String courseName) {
            System.out.println("可以任意的来回播放");
        }
    }
    
    public class Run {
        public static void main(String[] args) {
            LiveCourse liveCourse = new LiveCourse();
            liveCourse.study("直播课");
            ReplayCourse replayCourse = new ReplayCourse();
            replayCourse.study("录播课");
        }
    }
    
  • 业务继续发展,课程要做权限。没有付费的学员可以获取课程基本信息,已经付费的学员可以获得视频流,即学习权限。那么对于控制课程层面上至少有两个职责。我们可以把展示职责和管理职责分离开来,都实现同一个抽象依赖。设计一个顶层接口,创建 ICourse 接口:

    public interface ICourse {
        //获得基本信息
        String getCourseName();
    
        // 获得视频流
        byte[] getCourseVideo();
    
        // 学习课程
        void studyCourse();
    
        // 退款
        void refundCourse();
    
    }
    

    如果有免费课程,则不需要付款,还可以继续两个接口细分,

    public interface ICourseInfo {
        String getCourseName();
    
        byte[] getCourseVideo();
    }
    
    
    public interface ICourseManager {
        void studyCourse();
    
        void refundCourse();
    }
    

    新的课程可以实现部分接口,也可以实现全部接口

    public class LiveCourse implements ICourseInfo,ICourseManager {
        @Override
        public String getCourseName() {
            return null;
        }
    
        @Override
        public byte[] getCourseVideo() {
            return new byte[0];
        }
    
        @Override
        public void studyCourse() {
    
        }
    
        @Override
        public void refundCourse() {
    
        }
    }
    

二、方法单一职责原则

public class CourseMethod {

    private void modifyUserInfo(String userName, String... fileds) {
        userName = "Tom";
        //address = "Changsha";
    }

    private void modifyUserInfo(String userName, String address, boolean bool) {
        if (bool) {
        } else {
        }
        userName = "Tom";
        address = "Changsha";
    }
}

显然,上面的 modifyUserInfo()方法中都承担了多个职责,既可以修改 userName,也可以修改 address,甚至更多,明显不符合单一职责。那么我们做如下修改,把这个方法拆成两个:

public class CourseMethodTwo {

    private void modifyUserName(String userName) {
        userName = "Tom";
    }

    private void modifyAddress(String address) {
        address = "Changsha";
    }
}

这修改之后,开发起来简单,维护起来也容易。但是,我们在实际开发中会项目依赖,组合,聚合这些关系,还有还有项目的规模,周期,技术人员的水平,对进度的把控,很多类都不符合单一职责。但是,我们在编写代码的过程,尽可能地让接口和方法保持单一职责,对我们项目后期的维护是有很大。

posted @ 2020-02-29 15:14  李维维(levi)  阅读(520)  评论(0编辑  收藏  举报