单一职责原则

1. 单一职责原则的定义

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

又称单一功能原则,由罗伯特·C.马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中提出的。这里的职责是指类变化的原因,单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分(There should never be more than one reason for a class to change)。

该原则提出对象不应该承担太多职责,如果一个对象承担了太多的职责,至少存在以下两个缺点:

  1. 一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力;
  2. 当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费。

2. 单一职责原则的优点

单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。如果遵循单一职责原则将有以下优点。

  • 降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。
  • 提高类的可读性。复杂性降低,自然其可读性会提高。
  • 提高系统的可维护性。可读性提高,那自然更容易维护了。
  • 变更引起的风险降低。变更是必然的,如果单一职责原则遵守得好,当修改一个功能时,可以显著降低对其他功能的影响。

3. 单一职责原则的实现方法

单一职责原则是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。下面以交通工具运行方式为例介绍单一职责原则的应用。

【例】众所周知,交通工具有汽车这种陆地上的,也有飞机这种天上的,也有轮船,如果控制交通工具的类把所有交通工具的运行都放到一个方法去执行那么会出现这种情况:

/**
 * @Author lizeyu
 * @Date 2020/4/7 9:38
 */
public class single_test {
    public static void main(String[] args) {
        Vehicle car = new Vehicle("汽车");
        car.run(car.getname());
        Vehicle airPlane = new Vehicle("飞机");
        airPlane.run(airPlane.getname());
        Vehicle ship = new Vehicle("轮船");
        ship.run(ship.getname());
    }
}

class Vehicle{
    private String name;

    public Vehicle(String name) {
        this.name = name;
    }

    public String getname() {
        return name;
    }

    public void setname(String name) {
        this.name = name;
    }

    public void run(String name) {
        System.out.println(name+"交通工具是在陆地上运行");
    }
}

运行结果

汽车交通工具是在陆地上运行
飞机交通工具是在陆地上运行
轮船交通工具是在陆地上运行

由上面我们可以知道一个交通工具的总类去负责每种类型的交通工具的运行方式,它负责的太宽了,导致运行出现逻辑问题。我们大家都明白目前交通方式分为三类海陆空,我们讲交通工具类分为陆地交通水上交通天空交通,每一个类负责各自的运行方式。

第一次优化

/**
 * @Author lizeyu
 * @Date 2020/4/7 9:38
 */
public class single_test {
    public static void main(String[] args) {
        LandVehicle car = new LandVehicle("汽车");
        car.run(car.getName());

        AirVehicle airPlane = new AirVehicle("飞机");
        airPlane.run(airPlane.getName());

        WaterVehicle ship = new WaterVehicle("轮船");
        ship.run(ship.getName());
    }
}

class LandVehicle{
    private String name;

    public LandVehicle(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void run(String name) {
        System.out.println(name+"交通工具是在陆地上运行");
    }
}

class AirVehicle{
    private String name;

    public AirVehicle(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void run(String name) {
        System.out.println(name+"交通工具是在天上运行");
    }
}

class WaterVehicle{
    private String name;

    public WaterVehicle(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void run(String name) {
        System.out.println(name+"交通工具是在水上运行");
    }
}

运行结果

汽车交通工具是在陆地上运行
飞机交通工具是在天上运行
轮船交通工具是在水上运行

这样看起来就正常了,但是又有一个问题值得我们思考,一个很简单的问题居然需要创建三个类,内存消耗太大。我们有没有方法不需要这么浪费内存又做到单一职责呢?

第二次优化

/**
 * @Author lizeyu
 * @Date 2020/4/7 9:38
 */
public class single_test {
    public static void main(String[] args) {
        Vehicle transition = new Vehicle();

        transition.landRun("汽车");
        transition.airRun("飞机");
        transition.waterRun("轮船");
    }
}

class Vehicle{

    public void airRun(String name) {
        System.out.println(name+"交通工具是在天上运行");
    }

    public void waterRun(String name) {
        System.out.println(name+"交通工具是在水上运行");
    }

    public void landRun(String name) {
        System.out.println(name+"交通工具是在陆地上运行");
    }
}

运行结果

汽车交通工具是在陆地上运行
飞机交通工具是在天上运行
轮船交通工具是在水上运行

整体看我们并没有严格按照单一职责原则,这是什么意思呢?我们看到我们在客户端里,我们构造了海陆空三个类,为什么要这么做呢?因为我们交通工具类负责了三个职责。显然在类级别上违反了单一职责原则,但是我们这样做代码简单了很多,满足了程序设计的易读性。扩展简单,如果这时候又将汽车分为更细的类,那马我们只需要更改客户端的代码,而封装好的方法不需要改动,显然符合可扩展性。其它各种性质都可以满足。

这么看来我们可以得出结论,第二次优化以后虽然在类级别违反了单一职责原则,但是在方法上遵循了该原则,而且这样使得程序变得更加简单、更加适合使用。

4. 总结

单一职责原则注意事项和细节

  • 降低类的复杂度,一个类只负责一项职责
  • 提高类的可读性,可维护性
  • 降低变更引起的风险
  • 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码(类)级别违反单一职责原则;只有类中方法数量足够少,才可以在方法级别违反单一职责原则。

参考:http://c.biancheng.net/view/1327.html

已标记关键词 清除标记
相关推荐
程序员的必经之路! 【限时优惠】 现在下单,还享四重好礼: 1、教学课件免费下载 2、课程案例代码免费下载 3、专属VIP学员群免费答疑 4、下单还送800元编程大礼包 【超实用课程内容】  根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能!   套餐中一共包含2门MySQL数据库必学的核心课程(共98课时)   课程1:《MySQL数据库从入门到实战应用》   课程2:《高性能MySQL实战课》   【哪些人适合学习这门课程?】  1)平时只接触了语言基础,并未学习任何数据库知识的人;  2)对MySQL掌握程度薄弱的人,课程可以让你更好发挥MySQL最佳性能; 3)想修炼更好的MySQL内功,工作中遇到高并发场景可以游刃有余; 4)被面试官打破沙锅问到底的问题问到怀疑人生的应聘者。 【课程主要讲哪些内容?】 课程一:《MySQL数据库从入门到实战应用》 主要从基础篇,SQL语言篇、MySQL进阶篇三个角度展开讲解,帮助大家更加高效的管理MySQL数据库。 课程二:《高性能MySQL实战课》主要从高可用篇、MySQL8.0新特性篇,性能优化篇,面试篇四个角度展开讲解,帮助大家发挥MySQL的最佳性能的优化方法,掌握如何处理海量业务数据和高并发请求 【你能收获到什么?】  1.基础再提高,针对MySQL核心知识点学透,用对; 2.能力再提高,日常工作中的代码换新貌,不怕问题; 3.面试再加分,巴不得面试官打破沙锅问到底,竞争力MAX。 【课程如何观看?】  1、登录CSDN学院 APP 在我的课程中进行学习; 2、移动端:CSDN 学院APP(注意不是CSDN APP哦)  本课程为录播课,课程永久有效观看时长 【资料开放】 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化。  下载方式:电脑登录课程观看页面,点击右侧课件,可进行课程资料的打包下载。
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页