当前位置: 首页 > article >正文

七大设计原则之单一职责原则

目录

一、什么是单一职责原则?

二、如何判断是否满足单一职责原则?

三、单一职责原则是不是越单一就越好?


一、什么是单一职责原则?

        单一职责原则的英文名叫Single Responsibility Principle。所以,单一职责原则也简称SRP原则。这个原则相对其它原则是更好理解的,其实单从名字也是可以看出来这个原则是干啥的。我们先来看下单一职责原则的英文定义,A class or module should have a single responsibility。翻译过来就是,一个类或者模块应该只负责一个职责。所以说这个原则不仅是针对类的,也是针对模块的。其实往更大了说也可以针对一个服务,在进行服务拆分的时候,我们也要保证每个服务的职责单一,这样才能达到解耦的作用,也就可以提高可维护性。往更小了说,类中的方法也要尽可能的满足单一职责,从而使代码有更强的复用性以及可维护性。比如,我们定义一个方法handleUserAction用于处理用户的注册、登录、登出操作。

 public void handleUserAction(String action, String username, String password) {
        if ("register".equals(action)) {
            // 注册用户的逻辑
            System.out.println("Registering user: " + username);
        } else if ("login".equals(action)) {
            // 用户登录的逻辑
            System.out.println("Logging in user: " + username);
        } else if ("logout".equals(action)) {
            // 用户注销的逻辑
            System.out.println("Logging out user: " + username);
        }
    }

显然上面这种定义的方式,明显不符合单一职责原则。这种代码大概有如下几个缺点:

  • 可维护性差。假设其中注册用户的逻辑需要更改的话,就有可能会影响其它的逻辑,也就是降低了代码的可维护性。
  • 可读性差。这种方法里面有大量的if else也会降低代码的可读性,其实间接的也影响了可维护性。 
  • 可复用性差。从上面的例子,我们好像看不出复用性差。因为你不管注册、登录、登出都可以使用该方法。但是,如果我们直接把生成密码的逻辑写在注册用户里面。这样,如果后面,我们在重置密码的时候,只是想使用这个生成密码的逻辑,不就无法复用了!

总之,我们在编写代码时,务必避免编写大而全的代码。无论是小到方法,还是大到一个服务,都应尽量保证其职责单一。这样写出来的代码才具有更好的可维护性、可扩展性、可复用性和可读性。这样的代码才是满足高内聚、低耦合的高质量代码!

二、如何判断是否满足单一职责原则?

        在某些情况下,我们可以直接判断一个类或方法是否满足单一职责原则(Single Responsibility Principle, SRP)。例如,在之前提到的例子中,如果一个方法同时处理用户注册、登录和登出逻辑,同时还涉及密码生成等功能,显然这些职责之间存在耦合,违反了SRP。同样的,如果将完全不相关的类如用户类和订单类定义在同一个类中,这显然是不符合单一职责原则的。因为用户类应该只关注用户相关的操作,而订单类应该只关注订单相关的操作,两者的职责应该被明确分离。当然,有些场景下判断一个类是否满足SRP确实比较困难。这里举个经典的例子:用户类。相信每位写过代码的人肯定都定义过这个类。

@Data
public class User {
    private long id;
    private String name;
    private String email;
    private String telephone;
    private Date createTime;
    private Date updateTime;
    private Date lastLoginTime;
    private String avatarUrl;
    private String provinceOfAddress;
    private String cityOfAddress;
    private String regionOfAddress;
    private String detailedAddress;

 
}
  • 从用户层面看UserInfo 类包含所有与用户相关的信息,包括基本的用户信息(如用户名、电子邮件、电话号码等)和地址信息。从这个角度看,该类似乎满足单一职责原则,因为它处理的是用户信息。

  • 从更细粒度的业务层面看:如果将用户信息分为基本用户信息(如用户名、电子邮件、电话号码等)和地址信息,那么 UserInfo 类实际上承担了两个不同的职责:管理用户基本信息和管理用户地址信息。这种情况下,可以认为它不完全符合单一职责原则。

         那么,这个类到底满不满足单一职责原则呢?

       其实,对于这种类来判断到底满不满足SRP,就需要结合具体的业务场景了。如果说,在一个社交网络中,用户的地址只是用于展示,那么可以将用户基本信息和地址信息放在同一个类中,因为地址信息的比重较小。如果在电商平台中,用户的地址信息需要用于订单和物流处理,那么地址信息的比重较大,应该将地址信息拆分成独立的类,如 UserAddress,以提高类的内聚性和降低耦合性。

三、单一职责原则是不是越单一就越好?

        显然不是,任何事情都是过犹不及,对于单一职责原则也是,并不是职责越单一就越好。如果过度拆分,会导致系统中存在大量的小类,从而增加了系统的复杂性和管理成本,并且降低了代码的聚合性。如果在设计阶段一直追求极致的单一职责,就会分散更多的精力在这上面。此外,还有一种可能性是,你认为已经达到了单一职责,但随着业务的发展,这个职责又会变得不再单一。

       实际上,在真正的软件开发中,我们并不需要过于未雨绸缪,过度设计。因此,我们可以先写一个粗粒度的类来满足目前得业务需求就行了。随着业务的不断发展,如果这个粗粒度的类变得越来越庞大,代码量越来越多,这时我们就可以将可以将其拆分成几个更细粒度的类。这也就是我们常说的持续重构

补充:

判断一个类不满足单一职责原则的方法:

  1. 类中的代码行数、方法或者属性过多;
  2. 类依赖的其他类过多,或者依赖类的其他类过多;
  3. 私有方法过多;
  4. 比较难给类起一个合适的名字;
  5. 类中大量的方法都是集中操作类中的某几个属性。

http://www.kler.cn/a/465023.html

相关文章:

  • 你喜欢看哪类的网上视频教程?
  • HTML——75. 内联框架
  • 电子电气架构 --- 中央HPC架构
  • Git快速入门(三)·远程仓库GitHub以及Gitee的使用
  • 【NLP高频面题】用RNN训练语言模型时如何计算损失?
  • 音频进阶学习九——离散时间傅里叶变换DTFT
  • 【洛谷】5026、Lycanthropy 落水后水的高度
  • php获取字符串中的汉字
  • 图书项目:整合SSM
  • C++软件设计模式之解释器模式
  • 高职人工智能数据工程技术专业教学解决方案(2025年新专业)
  • 【每日学点鸿蒙知识】RelativeContainer组件、List回弹、Flutter方法调用、Profiler工具等
  • logback之配置文件使用详解
  • 使用 Bash 脚本中的time命令来统计命令执行时间:中英双语
  • 【开源社区openEuler实践】A-ops
  • OCP 认证专家零基础小白
  • Ruby自动化:用Watir库获取YouTube视频链接
  • 【Git系列】Git 分支操作:`git checkout -b test`与`git checkout test`的区别
  • OpenGL变换矩阵和输入控制
  • Linux---自动化工具Ansible模块教程
  • Go gin框架(详细版)
  • 【Triton-ONNX】如何使用 ONNX 模型服务与 Triton 通信执行推理任务上-Triton快速开始
  • 【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?
  • flutter组件————Row和Column
  • 【sql】CAST(GROUP_CONCAT())实现一对多对象json输出
  • 办公 三之 Excel 数据限定录入与格式变换