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

在软件开发领域,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未来:适应与创新
    PHP未来:适应与创新
    PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。 引言在编程世界中,PHP一直是网页开发的中流砥柱。作为一个从1994年就开始发展...
    编程 发布于2025-07-17
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符提取最后一行,在Postgresql中,您可能需要遇到与在数据库中的每个不同标识相关的信息中提取信息的情况。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: ...
    编程 发布于2025-07-17
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-07-17
  • PHP SimpleXML解析带命名空间冒号的XML方法
    PHP SimpleXML解析带命名空间冒号的XML方法
    在php 很少,请使用该限制很大,很少有很高。例如:这种技术可确保可以通过遍历XML树和使用儿童()方法()方法的XML树和切换名称空间来访问名称空间内的元素。
    编程 发布于2025-07-17
  • 版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    在时间戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源于遗留实现的关注,这些限制需要对当前的_timestamp功能进行特定的实现。 创建表`foo`( `Productid` int(10)unsigned not n...
    编程 发布于2025-07-17
  • CSS可以根据任何属性值来定位HTML元素吗?
    CSS可以根据任何属性值来定位HTML元素吗?
    靶向html元素,在CSS 中使用任何属性值,在CSS中,可以基于特定属性(如下所示)基于特定属性的基于特定属性的emants目标元素: 字体家庭:康斯拉斯(Consolas); } 但是,出现一个常见的问题:元素可以根据任何属性值而定位吗?本文探讨了此主题。的目标元素有任何任何属性值,属...
    编程 发布于2025-07-17
  • PHP与C++函数重载处理的区别
    PHP与C++函数重载处理的区别
    作为经验丰富的C开发人员脱离谜题,您可能会遇到功能超载的概念。这个概念虽然在C中普遍,但在PHP中构成了独特的挑战。让我们深入研究PHP功能过载的复杂性,并探索其提供的可能性。在PHP中理解php的方法在PHP中,函数超载的概念(如C等语言)不存在。函数签名仅由其名称定义,而与他们的参数列表无关。...
    编程 发布于2025-07-17
  • input: Why Does "Warning: mysqli_query() expects parameter 1 to be mysqli, resource given" Error Occur and How to Fix It?

output: 解决“Warning: mysqli_query() 参数应为 mysqli 而非 resource”错误的解析与修复方法
    input: Why Does "Warning: mysqli_query() expects parameter 1 to be mysqli, resource given" Error Occur and How to Fix It? output: 解决“Warning: mysqli_query() 参数应为 mysqli 而非 resource”错误的解析与修复方法
    mysqli_query()期望参数1是mysqli,resource给定的,尝试使用mysql Query进行执行MySQLI_QUERY_QUERY formation,be be yessqli:sqli:sqli:sqli:sqli:sqli:sqli: mysqli,给定的资源“可能发...
    编程 发布于2025-07-17
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-07-17
  • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
    编程 发布于2025-07-17
  • 如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
    编程 发布于2025-07-17
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-07-17
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-07-17
  • 找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    如何在mySQL中使用mySql 检索最大计数,您可能会遇到一个问题,您可能会在尝试使用以下命令:理解错误正确找到由名称列分组的值的最大计数,请使用以下修改后的查询: 计数(*)为c 来自EMP1 按名称组 c desc订购 限制1 查询说明 select语句提取名称列和每个名称...
    编程 发布于2025-07-17
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-07-17

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

Copyright© 2022 湘ICP备2022001581号-3