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

news2025/1/11 0:41:24

✨作者:猫十二懿

❤️‍🔥账号:CSDN 、掘金 、个人博客 、Github

🎉公众号:猫十二懿

单一职责原则

1、单一职责介绍

单一职责原则(SRP:Single Responsibility Principle)是指一个类或模块只负责单一的功能,不要存在多个导致类变更的原因。这个原则的核心思想就是将功能进行解耦,让单个类或模块只完成一项职责。)

简单来说:就是一个类只负责一个功能。

2、User用户例子

例如,一个User类应只关心表示用户本身的属性和行为,而不要将其它与用户无关的内容加入到这个类中去。如果一个类同时还负责了其他不相关的功能,比如用户地址、账户信息等,那么这个类的职责就不够单一了。这样,一旦修改了其中一个功能,可能就会影响到另外的功能,增加了维护和扩展的难度。

// 不遵循单一职责原则的代码实现
public class User {
    private String name;   // 姓名
    private String email;   // 邮箱
    private String address;  // 地址
    private double balance; // 收入

    public void updateUserInfo(String name, String email, String address) {
        this.name = name;
        this.email = email;
        this.address = address;
        // 更新用户信息...
    }
    
    public void deposit(double amount) {
        this.balance += amount;
        // 存款操作...
    }
}

在这个示例中,我们可以看到User类有两个职责:保存用户信息和用户账户操作。这就不符合单一职责原则,如果我们需要修改其中一个职责,可能会影响到另外一个职责的实现。

将上面用户的信息和用户账号的信息分离开

// 遵循单一职责原则的代码实现
public class User {
    private String name;
    private String email;
    private String address;

    public void updateUserInfo(String name, String email, String address) {
        this.name = name;
        this.email = email;
        this.address = address;
        // 更新用户信息...
    }
}

public class Account {
    private double balance;

    public void deposit(double amount) {
        this.balance += amount;
        // 存款操作...
    }
}

通过将用户信息和账户操作分别封装到不同的类中,我们使得每个类都只关注自己的职责,降低了代码间的耦合度,并且修改和扩展也更加方便和容易。

如果还是不太明白,再看下面的列子

3、交通工具列子

先看一段代码:

/**
 * 交通工具类
 *  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("轮船");
    }
}

运行结果如下:

image-20230412181239939

观察发现,这样的结果似乎不太符合我们的日常生活的习惯啊。摩托车、汽车在公路上运行肯定没问题,但是飞机和轮船呢???

3.1 改进一

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

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

在类定义上实现单一职责原则:不同的类,做不同的事情,但是每个类里面做的事情都相同的。

/**
 *   1. 遵守单一职责原则
 *   2. 但是这样做的改动很大,即将类分解,同时修改客户端
 *   3. 改进:直接修改Vehicle 类
 */
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拆解成了三个不同的类,再次运行。这样看起来就正常了吧。

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

image-20230412182305627

3.2 改进二

在方法定义上实现单一职责原则:不同的方法,做不同的事情,但是每个方法里面做的事情都相同的。

/**
 *   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方法进行了拆解,虽然这样的代码没有在类的层面上遵守单一职责原则,但是它却在方法层面上遵守了单一职责原则(一个方法都只做一件事情),同样可以做到正确的结果。

image-20230412182313746

4、单一职责原则总结

如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏

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

。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/567658.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二层交换机和三层交换机的区别

交换机端口是现代 IT 生态系统中网络通信过程的重要组成部分。通过将数据包从一个网段或网络设备转发到另一个网段或网络设备,它们可实现网络连接和可访问性。但是,并非所有交换机都是平等的。为您的网络选择合适的交换机归结为一个关键决策:…

【Prompt 思考】AI 产品的交互必须是对话和聊天吗?

AI 产品的交互必须是对话和聊天吗? 1. 界面设计2. 对话和聊天3. 提示工程4. 思考5. 工具辅助用户写prompt的界面自动优化promptChatWeb的提示器商店 1. 界面设计 对话没有预设用途:用户不知道它能做什么,其实是什么也能干。提供更好的用户体…

【2023 · CANN训练营第一季】基于昇腾910的TF网络脚本训练(ModelArts平台)

准备工作: 1.注册华为云账号,获取AK/SAK,授权ModelArts,并申请华为云代金券 2.获取训练数据集,并进行数据预处理,比如离线制作成tfrecords(建议,可选) 3.将数据集(训练脚本)上传到OBS 4.安装PycharmIDE及To…

一文细说vDSO机制原理

1. 什么是 vDSO 众所周知,操作系统为我们管理硬件资源,并以系统调用的方式对用户进程提供 API,但是 syscall 很慢,涉及陷入内核以及上下文切换。对于少量频繁调用的系统调用(比如获取当期系统时间)来说&am…

CDN 回源与CDN 多级缓存原理

一、什么是回源 回源是指浏览器在发送请求报文时,响应该请求报文的是源站点的服务器,而不是各节点上的缓存服务器(比如Nginx开启缓存),那么这个过程相对于通过各节点上的缓存服务器来响应的话就称作为回源。回源的请求…

Mac 原神电脑版下载安装使用教程,MacBook 上也可以玩原神了

最近发现了一个很棒的工具,他可以让你的 Mac 苹果电脑运行原神,而且画质和流畅度都是在线的,今天分享给大家 软件名字叫 playCover ,根据作者的介绍这款软件最初就是国外的一位博主想在 Mac 上玩原神特意开发的一款软件&#xff…

Faster R-CNN网络架构详解和TensorFlow Hub实现(附源码)

文章目录 一、RPN网络1. RPN网络简介2. backbone网络简介 二、Faster R-CNN网络架构1. Faster R-CNN网络简介2. 基于TensorFlow Hub实现Faster R-CNN 前言:Faster R-CNN的简介见 上一篇文章 一、RPN网络 1. RPN网络简介 RPN网络全称Region Proposal Network&#…

【星戈瑞】BODIPY-530/550氟化硼二吡咯荧光染料

BODIPY是一种荧光染料,其分子结构稳定、荧光强度高、荧光寿命长、光谱范围广,因此在许多领域都有应用。在生物医学领域,BODIPY作为荧光探针,可用于细胞成像、生物分子探测、药物筛选等方面。例如,一些研究者将BODIPY修…

如何在华为OD机试中获得满分?Java实现【计算某字符出现次数】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

今天面了个字节拿23k出来的小伙,让我见识到了什么才是天花板...

2023年堪称大学生就业最难的一年,应届毕业生人数是1158万,再次刷新记录。 但是我观察到一个数据,那就是已经就业的毕业生中,计算机通信等行业最受毕业生欢迎! 计算机IT行业薪资高,平均薪资是文科其他岗位的…

Java之旅(二)

Java安装 检查您是否在 Windows PC 上安装了 Java,请在开始栏中搜索 Java 或在命令提示符 (cmd.exe) 中键入以下内容:java -version 在 Windows 上安装 Java: 转到“系统属性”(可以在控制面板 > 系统和安全 > 系统 >…

android aidl及binder基础知识总结

1、什么是binder binder是android framework提供的,用于跨进程方法调用的机制,具有安全高效等特点。 我们知道,在 Android 系统中,每个应用程序都运行在一个独立的进程中,各个进程之间需要进行数据交换和调用&#x…

元宇宙应用领域-医疗

元宇宙(Metaverse)是一个虚拟空间,用户可以通过数字技术和设备在其中生活和工作。元宇宙由一系列相关的技术和应用组成,包括区块链、虚拟现实、增强现实、人工智能、网络安全、大数据和云计算等。 元宇宙是一种新型的虚拟空间&am…

【加解密】bcryptjs | CryptoJS | JSEncrypt | node-rsa 加密| 解密 | RSA | ASE | MD5

加解密 1、 bcryptjs 解密 - 只可加密,比对密码,不可解密 下载 npm i bcryptjs 作用:字符串加密,已加密的字符串不可破解,只可比对。优点:加密的字符不可解密缺点:已加密的字符不可解密&#…

【TI毫米波雷达笔记】IWR6843AOPEVM开箱功能测试

【TI毫米波雷达笔记】IWR6843AOPEVM开箱功能测试 我用的是IWR6843AOPEVM-G 相关资源可以在ti官网下载 要用的软件是 TI官方上位机 mmWave_Demo_Visualizer 可以用网页版 也可以用软件包 建议先上网页版看看版本支不支持对应的板子 网页版: dev.ti.com/gallery/…

CMake之安装

目录 公共选项安装目标安装文件安装目录安装导出 公共选项 install有多个签名,这些签名公用的选项有以下: DESTINATION:指定文件要安装的目录,可以是相对路径或绝对路径。 相对路径:会使用 CMAKE_INSTALL_PREFIX 作为…

rttread-nano 使用记录:rt_kprintf函数格式化打印无法左对齐

rttread-nano 使用记录:rt_kprintf函数格式化打印无法左对齐 今天用rt_kprintf函数打印输出一个表格,为了表格好看每一列我都使用格式化参数-负号符号设置为了左对齐,但是发现无法打印,也无法打印浮点数,换成微库的pri…

通过注册表显示和隐藏“我的电脑”、“回收站”等图标

注册表路径: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel 其中{208D2C60-3AEA-1069-A2D7-08002B30309D}是我的电脑,值的类型为REG_DWORD,改为0后隐藏,1代表显示。 其…

Try ‘apt --fix-broken install’ with no packages解决办法

在Ubuntu中用apt-get安装软件,系统报出Unmet dependencies错误。 Unmet dependencies. Try ‘apt --fix-broken install’ with no packages (or specify a solution) 解决方案如下: sudo apt --fix-broken install sudo apt-get update sudo apt-get u…

建筑专业应届生零基础想学习数据分析,职业发展前景如何?能学会吗?

建筑应届生零基础想学习数据分析,职业发展前景如何?能学会吗? 当然是能学会的,但如果想要有发展前景,不仅是会数据分析而已,更需要实战能力,能够结合不同的业务进行分析,掌握各种常见…