SHOW ME THE CODE - 面向对象程序设计之 - 单一职责原则

今天我们从代码的角度来讲一讲,到底什么是:单一职责原则

SRP的定义

Single Responsibility Principle, 单一职责原则
单一职责原则(Single Responsibility Principle,SRP)最早是由罗伯特·C·马丁(Robert C. Martin)在他的经典著作《敏捷软件开发:原则、模式与实践》(Agile Software Development: Principles, Patterns, and Practices)中提出的。这本书于2003年首次出版,其中探讨了敏捷软件开发的原则、模式和实践。

在该书中,马丁将单一职责原则描述为:“一个类应该只有一个导致它变化的原因。”这个简明的定义强调了类的内聚性和责任的单一性,表明一个类应该只负责一个明确的任务或功能,而不应该包含多个不相关的功能或责任。

怎么理解单一职责

一个类只有一个职责,也可以理解只承担一个角色。即一个类应该专注于完成一个特定的任务或者扮演一个特定的角色,而不应该包含多个不相关的职责或角色。这样可以提高类的内聚性,使得类的设计更加清晰、简洁和易于理解。

例子1:现代化的流水线

大家可以试想一下,为什么现代化的工厂都是流水线作业?一台手机,一台汽车,一台飞机,从那么多的零部件如何组件成为了消费者手上的产品?流水线上的每一个环节,可以理解了一个类,他们都只专注于一件事情。

比如,汽车制造过程中的几个重要的环节:

  • 冲压工序
  • 焊接工序
  • 涂装工序
  • 总装工序

一条现代化的生产线,最终通过流水线的作业形式,结合信息技术,将生产过程中的各个具备不同职责的工序有机的整合起来,最终形成一条完整的生产线,从而实现高效、优质、低成本地生产产品。

例子2:部队

从古至今,部队都是按不同的兵种划分,古代有骑兵,有弓箭兵,有长枪兵,有水兵,有陆兵。现代,有海、陆、空,有步兵,有坦克兵,有炮兵,有医疗兵,有航空兵,还有信息化部队,后勤部队等等。

企业的运作

现代企业需要IT系统来支撑公司的日常运营工作,而企业的运营是由不同角色的人通过各种不同的流程有机的联系在一起才能使得企业高效的运转。

使用IT系统的人,来自于企业不同的部门,承担着不同的岗们职责,而我们设计IT系统的时候,也应该和企业的组织架构保持一致。比如说,HR和财务就是不同的角色。HR负责员工信息的管理,而员工奖金的分配,则通常是财务的事情。

SHOW ME THE CODE - 年终奖的计算该放在哪里

不正确的方式 - 违反SRP原则

// 员工基本信息类
public class Employee {private String name;private int employeeId;private double salary;public Employee(String name, int employeeId, double salary) {this.name = name;this.employeeId = employeeId;this.salary = salary;}public double calculateBonus() {double bonus = 0.0;// 假设这里有一些计算年终奖金的复杂逻辑......return bonus;}
}

我们看到,Bouns的计算放在了Employee 这个类里边,这里实际上就已经违反了单一职责原则,Employee 不仅负责员工基本信息的管理,还要负责年终奖金的计算。

Employee类涉及了两类现实中的角色,HR和财务人员。
现实中HR会负责员工信息的收集和更新。而年终奖的发放通常是需要结合企业的营收,中心的绩效,部门的绩效,以及个人绩效等多方面因素来决定,具体的计算逻辑应该由财务决定,而且有一些数据,只允许财务人员才能够看。

我们员工年终的信息应该从Payroll类中获取,而具体的计算逻辑则放在年终奖计算器BonusCalculator中。

正确的方式 - 职责分离

重构后的代码应该如下,这样就不违反单一职责原则了。Enployee不会包含除了员工信息管理之外的其它职责,Bonus的计算有专门的工具类来实现。


public class Employee {private String name;private int employeeId;private double salary;public Employee(String name, int employeeId, double salary) {this.name = name;this.employeeId = employeeId;this.salary = salary;}
}public class Payroll
{private BonusCalculator bonusCalculator;public void setBonusCalculator(BonusCalculator bonusCalculator){this.bonusCalculator = bonusCalculator;}public double getBouns(Employee employee){return bonusCalculator.calculateBonus(employee);}
}public class BonusCalculator {public double calculateBonus(Employee employee) {double bonus = 0.0;// 假设这里有一些计算年终奖金的复杂逻辑......return bonus;}
}

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

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

相关文章

贪吃蛇撞墙功能的实现 和自动行走刷新地图 -- 第三十天

1.撞墙 1.1最初的头和尾指针要置为空,不然是野指针 1.2 在增加和删除节点后,判断是否撞墙,撞墙则初始话蛇 1.3在撞墙后初始化蛇,如果头不为空就撞墙,得定义临时指针指向头,释放头节点 2.自动刷新地图 2.1…

从Kafka的可靠性设计体验软件设计之美

目录 1. Kafka可靠性概述 2. 副本剖析 2.1 什么是副本 2.2 副本失效场景 2.3 数据丢失场景 2.4 解决数据丢失方案 3. 日志同步机制 4. 可靠性分析 1. Kafka可靠性概述 Kafka 中采用了多副本的机制,这是大多数分布式系统中惯用的手法,以此来实现水平扩…

Web-SpringBootWen

创建项目 后面因为报错,所以我把jdk修改成22,仅供参考。 定义类,创建方法 package com.start.springbootstart.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotati…

java-Spring-(MyBatis框架-xml管理)

目录 前置条件 xml与注解比较 1.1 xml定义 1.2 和SQL注解比较 建包准备 插入数据 ​编辑 更新数据 删除数据 查询数据 查看单字段查询 🏷💣前置条件 创建一个spring boot 初始化的项目 🏷💣xml与注解比较 1.1 xml定义 …

以太网口硬件知识分享

一、了解网口通信基本原理 实现网络通信实质上是PHY与MAC及RJ45接口实现信号传输。MAC 就是以太网控制器,MAC属于数据链路层,主要负责把数据封装成帧,对帧进行界定实现帧同步。对MAC地址和源MAC地址及逆行相应的处理并对错误帧进行处理。PHY…

2017美亚杯--个人赛

1、Gary的笔记本电脑已成功取证并制作成镜像 (Forensic Image),下列哪个是其MD5哈希值。A.0CFB3A0BB016165F1BDEB87EE9F710C9 B.5F1BDEB87EE9F710C90CFB3A0BB01616 C.A0BB016160CFB3A0BB0161661670CFB3 D.16160CFB3A0BB016166A0BB016166167 E.FB3A0BB016165 B016166…

[Flutter3] 记录Dio的简单封装(一)

文章目录 效果使用ResponseEntity类DioManager封装_onResponse / _onDioException 的设计Response的处理catch处理 效果 请求成功/失败/异常的日志输出效果 成功: 失败:500 失败:404 网络异常: 使用 举个使用的例子, 在调用 DioManager的时候, 直接通过返回值的状态, 来…

Qt 把.exe打包成安装文件形式

目录 1.下载工具 Qt Installer Framework2.将bin文件添加到环境变量3.拷贝startmenu示例-备用4.准备Qt Release打包好的程序5.把Release打包好的程序放到packages\org.qtproject.ifw.example\data文件夹下6.生成安装包7.修改安装包图标8.修改主程序程序安装引导-创建快捷键9.添…

Linux---自定义协议

应用层协议 一、协议定制---以网络计算器为例 网络计算机功能---进行-*/^&|的运算并返回结果 请求和响应的结构体如下 // Protocol.hpp #pragma once #include <iostream> #include <memory> class Request { public:Request(){}Request(int data_x, int da…

苹果AI终于来了!从2.7到30亿四款大模型代码全开源,AI技术持续“狂飙”|钛媒体AGI

&#xff08;图片来源&#xff1a;Apple官网&#xff09; 苹果公司突然公布了一则大新闻。 北京时间4月25日凌晨&#xff0c;苹果在 Hugging Face 平台上发布一个“具有开源训练和推理框架的高效语言模型”&#xff0c;名为 OpenELM。 据了解&#xff0c;OpenELM有四种尺寸&…

Magnet for Mac:高效窗口管理工具

Magnet for Mac是一款专为Mac用户设计的窗口管理工具&#xff0c;旨在帮助用户更高效地管理和布局多个应用程序窗口&#xff0c;提升工作效率。 Magnet for Mac v2.14.0中文免激活版下载 这款软件拥有直观易用的界面和丰富的功能&#xff0c;支持用户将屏幕分割成多个区域&…

Linux操作系统的安装与配置

目录 (1)实验目的&#xff1a; (2)实验内容&#xff1a; (3)实验原理&#xff1a; (4)实验步骤&#xff1a; 1.先下载vmware workstation pro软件&#xff0c;下载地址:https://www.vmware.com/products/workstation-pr o/workstation-pro-evaluation.html 2.下载完成后&…

vue+element 树形结构 改成懒加载模式(原理element有),这里只做个人理解笔记

1 找到属性标签添加 lazy 和 :load"loadNode" 这两个属性 2 引入树形接口,并和后端约定好传值,(拿我的举例 第一次获取全部父级默认第一次传参数:{ parentId : 0},可获取全部父级 第二次通过点击的子级把子级id传进去,这一步就用到了:load"loadNode&quo…

路由器使用docker安装mysql和redis服务

路由器使用docker安装mysql和redis服务 1.先在路由器中开启docker功能 &#xff08;需要u盘 或者 移动硬盘&#xff09; 2. docker 管理地址 :http://192.168.0.1:11180/#/ 3. 拉取镜像 4. mysql容器参数设置 MYSQL_ROOT_PASSWORD 5. redis 容器设置 开发经常需要用到 &…

Synchronized关键字的深入分析

一、引言 在多线程编程中&#xff0c;正确地管理并发是确保程序正确运行的关键。Java提供了多种同步工具&#xff0c;其中synchronized关键字是最基本且最常用的同步机制之一。本文旨在深入解析synchronized的实现原理&#xff0c;探讨其在不同应用场景中的使用&#xff0c;并…

​解析什么是物联网接入网关?-天拓四方

随着物联网技术的飞速发展&#xff0c;越来越多的设备、传感器和系统被连接到互联网&#xff0c;形成了一个庞大的、相互连接的智能网络。在这个网络中&#xff0c;物联网接入网关扮演着至关重要的角色&#xff0c;它不仅是连接物联网设备和云平台的桥梁&#xff0c;还是实现设…

数据结构-二叉树-堆(二)

一、建堆的时间复杂度问题 1、除了向上调整建堆&#xff0c;我们还可以向下调整建堆。不能在根上直接开始向下调整。这里的条件就是左右子树必须都是大堆或者小堆。我们可以倒着往前走&#xff0c;可以从最后一个叶子开始调整。但是从叶子开始调整没有意义。所以我们可以从倒数…

mysql的多表查询和子查询

多表查询&#xff1a;查询数据时&#xff0c;需要使用多张表来查询 多表查询分类&#xff1a; 1.内连接查询 2.外连接查询 3.子查询 笛卡尔积&#xff1a; create table class (id int primary key auto_increment,name varchar(10) ); create table student (id int primar…

serdes 同轴电缆和双绞线接法

1、同轴电缆 Coaxial Cable 2、双绞线STP&#xff08;Shielded Twisted Pair&#xff09; 比如我们用的车载camera一般就只需要接一路即可&#xff0c;RIN接camera&#xff0c; RIN-通过电容接地。

python基础——正则表达式

&#x1f4dd;前言&#xff1a; 这篇文章主要想讲解一下python中的正则表达式&#xff1a; 1&#xff0c;什么是正则表达式 2&#xff0c;re模块三匹配 3&#xff0c;元字符匹配 4&#xff0c;具体示例 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&am…