设计模式七大原则——单一职责原则

news/2025/2/25 16:15:29

1.什么是单一职责原则?

首先我们可以对某个类来说,即一个类应该只负责一项职责。如类A负责两个不同职责: 职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。

我们来看下面这段代码:👇👇👇

package com.szh.principle.singleresponsibility;

/**
 * 交通工具类
 *  方式1
 *  1. 在方式1的run方法中,违反了单一职责原则
 *  2. 解决的方案非常的简单,根据交通工具运行方法不同,分解成不同类即可
 */
class Vehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + " 在公路上运行....");
    }
}

public class SingleResponsibility1 {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();
        vehicle.run("摩托车");
        vehicle.run("汽车");
        vehicle.run("飞机");
        vehicle.run("轮船");
    }
}

乍一看没什么问题吧,但是我们运行之后,看到的结果似乎就不太合乎思维逻辑了。摩托车、汽车在公路上运行肯定没问题,但是飞机和轮船呢???(你是故意找茬是不是?)


2.改进代码一

对于上面代码案例中的问题,想必大家也都看出来了,Vehicle这个类负责的职责太多了,它既要管摩托车、汽车这种在公路上跑的,还要去管飞机这种在天上飞的,这就使得Vehicle这个类粒度太粗了,后期如果做出对公路方法的修改时,可能还会影响到其他的业务功能。

所以我们考虑将Vehicle这个类进行分解,分解为多个类,各干各的、各司其职。

package com.szh.principle.singleresponsibility;

/**
 * 方案2的分析
 *   1. 遵守单一职责原则
 *   2. 但是这样做的改动很大,即将类分解,同时修改客户端
 *   3. 改进:直接修改Vehicle 类,改动的代码会比较少=>方案3
 */
class RoadVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + "在公路运行");
    }
}

class AirVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + "在天空运行");
    }
}

class WaterVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + "在水中运行");
    }
}

public class SingleResponsibility2 {
    public static void main(String[] args) {
        RoadVehicle roadVehicle = new RoadVehicle();
        roadVehicle.run("摩托车");
        roadVehicle.run("汽车");

        AirVehicle airVehicle = new AirVehicle();
        airVehicle.run("飞机");

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

此时,我们将Vehicle拆解成了三个不同的类,再次运行。这样看起来就正常了吧。

不过也有人说,这样的改动比较大,也即直接在类的层面上做了修改,我们能不能不改动这个类,而是对它的方法做修改呢?答案是可以的。


3.改进代码二

package com.szh.principle.singleresponsibility;

/**
 * 方式3的分析
 *   1. 这种修改方法没有对原来的类做大的修改,只是增加方法
 *   2. 这里虽然没有在类这个级别上遵守单一职责原则,但是在方法级别上,仍然是遵守单一职责
 */
class Vehicle2 {
    public void runRoad(String vehicle) {
        System.out.println(vehicle + " 在公路上运行....");
    }

    public void runAir(String vehicle) {
        System.out.println(vehicle + " 在天空上运行....");
    }

    public void runWater(String vehicle) {
        System.out.println(vehicle + " 在水中行....");
    }
}

public class SingleResponsibility3 {
    public static void main(String[] args) {
        Vehicle2 vehicle2  = new Vehicle2();
        vehicle2.runRoad("汽车");
        vehicle2.runAir("飞机");
        vehicle2.runWater("轮船");
    }

}

此时我们并未将类进行拆解,而是将之前的run方法进行了拆解,虽然这样的代码没有在类的层面上遵守单一职责原则,但是它却在方法层面上遵守了单一职责原则,同样可以做到正确的结果。


4.单一职责原则总结

  1. 降低类的复杂度,一个类只负责一项职责。
  2. 提高类的可读性、可维护性。
  3. 降低代码变更引起的风险。
  4. 通常情况下,我们应当遵守单一职责原则。只有逻辑足够简单的情况下,才可以在代码级违反单一职责原则;而只有类中方法数量足够少的时候,才会建议在方法级别保持单一职责原则。

http://www.niftyadmin.cn/n/711127.html

相关文章

Arimoto–Blahut algorithm (Mathematica)

该算法用于近似计算离散信道的容量。参数pyx是信道的转移概率矩阵p(y|x)。 转载于:https://www.cnblogs.com/zhy2002/archive/2010/05/25/1743303.html

ELK系列~对fluentd参数的理解

这段时候一直在研究ELK框架,主要集成在对fluentd和nxlog的研究上,国内文章不多,主要看了一下官方的API,配合自己的理解,总结了一下,希望可以帮到刚入行的朋友们! Fluentd(日志收集与…

设计模式七大原则——接口隔离原则

1.什么是接口隔离原则? 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口范围上。 2.对应代码 上面这张图呢,就违反了接口隔离原则。它对应的代码如下:👇👇👇 pac…

ADO.NET笔记——使用Command执行增删改操作,通过判断ExecuteNonQuery()返回值检查是否操作成功...

相关知识: ExecuteNonQuery()方法:执行CommandText属性所制定的操作,返回受影响的记录条数。该方法一般用来执行SQL中的UPDATE、INSERT和DELETE等操作对于UPDATE、INSERT和DELETE语句,执行成功返回值为该命令所影响的行数&#xf…

为自定义配置的编辑提供”智能感知”的支持

当我们在设计一个框架的时候,必然会涉及一系列的配置。为了让使用者更好地使用你提供的框架,让他们能够容易地维护这些配置是一项基本的要求。对于一些配置过于复杂的框架,比如EnterLib,比如WCF,往往会提供一个配置的工…

设计模式七大原则——依赖倒转原则

1.什么是依赖倒转原则? 高层模块不应该依赖低层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。依赖倒转 (倒置) 的中心思想是面向接口编程。依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西…

Windows下PHP+Eclipse开发环境搭建 及错误解决(apache2.2服务无法启动 发生服务特定错误:1)...

前言 Eclipse与php/apache的关系:Eclipse只是用来写代码的,如果想要在浏览器查看运行效果就要让php/apache的运行目录指向你的代码目录。Eclipse貌似不会自己和apache/php通信。 ApachePHP 首先按照这个链接配置apachephp: http://www.cnblog…

设计模式七大原则——里氏替换原则

1.什么是里氏替换原则? 我们都知道,在面向对象编程中有三大特性(封装、继承、多态),在这里我们来说 继承 这个东西。 继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约&#xff…