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

在软件开发领域,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]删除
最新教程 更多>
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符在postgresql中提取最后一行,您可能需要遇到与数据集合中每个不同标识的信息相关的信息。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: id dat...
    编程 发布于2025-03-11
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-03-11
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-03-11
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-03-11
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    答案: 在大多数现代编译器中,while(1)和(1)和(;;)之间没有性能差异。编译器: perl: 1 输入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    编程 发布于2025-03-11
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-03-11
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-03-11
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-03-11
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-03-11
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-03-11
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-03-11
  • 如何使用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-11
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-03-11
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-03-10

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

Copyright© 2022 湘ICP备2022001581号-3