上面,我们有一个名为 userService 的结构。它有两个属性:db,负责与关系数据库通信;amqpChannel,支持与 RabbitMQ 消息服务通信。

UserService 实现了一个名为 Create 的方法。在此方法中,我们将接收到的用户信息存储在数据库中,然后将数据发布到 RabbitMQ。
可见userService中Create方法的职责不只是一个,而是两个:在数据库中存储信息和在RabbitMQ队列中发布消息。

这可能会导致几个问题,例如:

在下面的代码中,我们修改结构以尊重 SRP。一探究竟:

请注意,我们已将职责分为三个不同的部分:存储库 UserRepository 将用户保存到数据库,发布者 UserPublisher 将消息发送到 RabbitMQ,以及服务 UserService 协调这两个操作。

这样,每个组件负责特定的、独立的任务,方便代码的维护和演进,此外还允许这些部分中的每一个被替换或改进而不影响其他部分。例如,如果需要更改所使用的数据库,只需更换存储库即可。如果需要改变传播形式,只需更换发布者即可。

值得一提的是,执行两个不同的任务和委派其执行之间存在细微的区别。在userService.Create的原始示例中,在一个地方执行了两个操作,违反了单一责任原则。重构后,我们将执行委托给不同的结构体,Create 方法只负责协调这个流程。

为了在此示例中应用 SRP,我们最终还实施了其他一些 SOLID 原则:

在本系列的下一篇文章中,我将通过具体示例对它们进行更详细的解释。

再见,伙计们!

参考:
SOLID:面向对象设计的前 5 个原则
Clean Coder 博客 - 单一职责原则

","image":"http://www.luping.net","datePublished":"2024-07-29T22:18:29+08:00","dateModified":"2024-07-29T22:18:29+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > Princípios SOLID em GoLang - 单一职责原则 (SRP)

Princípios SOLID em GoLang - 单一职责原则 (SRP)

发布于2024-07-29
浏览:369

在软件开发领域,SOLID原则告诉我们如何组织函数和数据,以便我们的代码:

  • 容忍变化
  • 简单易懂
  • 成为可在许多软件系统中使用的组件的基础

术语 SOLID 是五个设计假设的缩写,如下所述:

(S) 单一职责原则:“一个模块必须有且只有一个改变的理由”
(O) 开放/封闭原则:“软件工件必须对扩展开放,但对修改关闭”
(L)里氏替换原则:“派生类必须可以被其基类替换”
(一)接口隔离原则:“不应该强迫一个类实现它不会使用的接口和方法”
(D) 依赖倒置原则:“依赖于抽象而不是实现”

SOLID 和 Go 语言

Princípios SOLID em GoLang - Single Responsability Principle (SRP)

SOLID 是为面向对象编程而设计的,众所周知,GoLang 并不是采用这种范式的语言。但是,我们可以使用它提供的资源来满足 OOP 方法。例如,Go 没有继承支持,但这个想法可以通过其组合支持来补偿。类似地,可以使用接口创建一种多态性。

在这篇文章(共 5 篇文章中的第一篇)中,我打算通过与我们日常遇到的情况接近的示例来详细说明第一个原则。

单一职责原则(SRP)

我们已经知道该术语的含义,现在是时候学习如何在 GoLang 中实现它了。
在这种语言中,我们可以将这一原则定义为“一个函数或类型必须有一项且仅有一项工作,以及一项且仅有一项责任”,让我们看下面的代码:

上面,我们有一个名为 userService 的结构。它有两个属性:db,负责与关系数据库通信;amqpChannel,支持与 RabbitMQ 消息服务通信。

UserService 实现了一个名为 Create 的方法。在此方法中,我们将接收到的用户信息存储在数据库中,然后将数据发布到 RabbitMQ。
可见userService中Create方法的职责不只是一个,而是两个:在数据库中存储信息和在RabbitMQ队列中发布消息。

这可能会导致几个问题,例如:

  • 难以维护:如果其中一项需求发生变化,例如用户数据的序列化方式,您将不得不修改Create方法的逻辑,即使这与您的主要职责无关,即将数据保存到数据库中。
  • 测试难度:由于 Create 方法有两个不同的职责,因此您必须为每个方法创建测试,这可能很困难且费力。
  • 不必要的耦合:将用户数据发布到 RabbitMQ 队列的逻辑完全独立于将该数据保存到数据库的逻辑。在同一个方法中混合这两种职责会产生不必要的耦合。

在下面的代码中,我们修改结构以尊重 SRP。一探究竟:

请注意,我们已将职责分为三个不同的部分:存储库 UserRepository 将用户保存到数据库,发布者 UserPublisher 将消息发送到 RabbitMQ,以及服务 UserService 协调这两个操作。

这样,每个组件负责特定的、独立的任务,方便代码的维护和演进,此外还允许这些部分中的每一个被替换或改进而不影响其他部分。例如,如果需要更改所使用的数据库,只需更换存储库即可。如果需要改变传播形式,只需更换发布者即可。

值得一提的是,执行两个不同的任务和委派其执行之间存在细微的区别。在userService.Create的原始示例中,在一个地方执行了两个操作,违反了单一责任原则。重构后,我们将执行委托给不同的结构体,Create 方法只负责协调这个流程。

为了在此示例中应用 SRP,我们最终还实施了其他一些 SOLID 原则:

  • 接口隔离原则 (ISP):每个接口代表一个职责。 UserRepository 和 UserPublisher 都是只有一种方法的接口,每个方法代表一个职责。
  • 依赖倒置原则(DIP):userService结构依赖于抽象(接口)而不依赖于具体实现,也就是说,它不知道UserRepository和UserPublisher的具体实现,只知道他们实现的接口。
  • 开放/封闭原则(OCP):代码对于扩展是开放的,因为可以轻松添加新的存储库或发布者,而无需修改 userService。

在本系列的下一篇文章中,我将通过具体示例对它们进行更详细的解释。

再见,伙计们!

参考:
SOLID:面向对象设计的前 5 个原则
Clean Coder 博客 - 单一职责原则

版本声明 本文转载于:https://dev.to/waliqueiroz/principios-solid-em-golang-single-responsability-principle-srp-af5?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入数据时如何修复“常规错误:2006 MySQL 服务器已消失”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2024-12-18
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-12-18
  • 大批
    大批
    方法是可以在对象上调用的 fns 数组是对象,因此它们在 JS 中也有方法。 slice(begin):将数组的一部分提取到新数组中,而不改变原始数组。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index p...
    编程 发布于2024-12-18
  • 除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-12-18
  • 如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    在 PHP 中组合关联数组在 PHP 中,将两个关联数组组合成一个数组是一项常见任务。考虑以下请求:问题描述:提供的代码定义了两个关联数组,$array1 和 $array2。目标是创建一个新数组 $array3,它合并两个数组中的所有键值对。 此外,提供的数组具有唯一的 ID,而名称可能重合。要求...
    编程 发布于2024-12-18
  • 尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    解决 PHP 中的 POST 请求故障在提供的代码片段中:action=''而不是:action="<?php echo $_SERVER['PHP_SELF'];?>";?>"检查 $_POST数组:表单提交后使用 var_dump 检查 $_POST 数...
    编程 发布于2024-12-18
  • 为什么我的 Spring Boot 应用程序不自动创建数据库架构?
    为什么我的 Spring Boot 应用程序不自动创建数据库架构?
    在 Spring Boot 中自动创建数据库架构启动 Spring Boot 应用程序时,可能会遇到自动创建数据库架构的问题。以下故障排除步骤旨在解决此问题:1.实体类包:确保实体类位于使用@EnableAutoConfiguration注解的类的同一个包或子包中。否则,Spring 将不会检测实体...
    编程 发布于2024-12-18
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-12-18
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-12-18
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-12-18
  • CSS3 过渡是否提供事件来检测起点和终点?
    CSS3 过渡是否提供事件来检测起点和终点?
    了解 CSS3 过渡事件CSS3 过渡允许在 Web 元素上实现流畅的动画和视觉效果。为了增强用户体验并使操作与这些转换同步,监控其进度非常重要。本文解决了 CSS3 是否提供事件来检查过渡何时开始或结束的问题。W3C CSS 过渡草案W3C CSS 过渡草案规定CSS 转换会触发相应的 DOM 事...
    编程 发布于2024-12-18
  • Java 中可以手动释放内存吗?
    Java 中可以手动释放内存吗?
    Java 中的手动内存释放与垃圾回收与 C 不同,Java 采用托管内存框架来处理内存分配和释放由垃圾收集器 (GC) 自动执行。这种自动化方法可以提高内存利用率并防止困扰 C 程序的内存泄漏。Java 中可以手动释放内存吗?由于 Java 的内存管理是由GC,它没有提供像 C 中的 free() ...
    编程 发布于2024-12-18
  • Java 1.6 中如何可靠地确定文件是否为符号链接?
    Java 1.6 中如何可靠地确定文件是否为符号链接?
    在 Java 1.6 中验证符号链接确定符号链接的存在对于各种文件处理操作至关重要。在 Java 中,识别符号链接时需要考虑一些潜在问题,特别是在目录遍历的上下文中。检查符号链接的一种常见方法是比较文件的绝对路径和规范路径。规范路径表示文件的标准化路径,而绝对路径可能包括符号链接。传统上,概念是如果...
    编程 发布于2024-12-17
  • 如何使背景颜色透明,同时保持文本不透明?
    如何使背景颜色透明,同时保持文本不透明?
    背景颜色的不透明度而不影响文本在 Web 开发领域,实现透明度通常对于增强视觉吸引力和网站元素的功能。一项常见的要求是对 div 背景应用透明度,同时保留所包含文本的不透明度。这可能会带来挑战,特别是在确保跨浏览器兼容性方面。rgba 解决方案最有效且得到广泛支持的解决方案是利用“RGBA”(红、绿...
    编程 发布于2024-12-17
  • PHP 字符串比较:`==`、`===` 或 `strcmp()` – 您应该使用哪个运算符?
    PHP 字符串比较:`==`、`===` 或 `strcmp()` – 您应该使用哪个运算符?
    PHP 中的字符串比较:'=='、'===' 或 'strcmp()'?PHP 中的字符串比较PHP 可以使用不同的运算符来完成,例如“==”、“===”或“strcmp()”函数。此比较涉及检查两个字符串是否相等。'==' 与 ...
    编程 发布于2024-12-17

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3