上面,我们有一个名为 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
浏览:744

在软件开发领域,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]删除
最新教程 更多>
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call ...
    编程 发布于2025-03-10
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符在postgresql中提取最后一行,您可能需要遇到与数据集合中每个不同标识的信息相关的信息。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: id dat...
    编程 发布于2025-03-10
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-03-10
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError: SomeClass...
    编程 发布于2025-03-10
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-03-10
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-03-10
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-03-10
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-03-10
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-03-10
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-03-10
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-03-10
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-03-10
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-03-10
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-03-10

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

Copyright© 2022 湘ICP备2022001581号-3