这个类是否违反了单一职责原则?

Lew*_*wis 3 python single-responsibility-principle solid-principles

我已经编写了UserService关于用户的类(在逻辑层,而不是持久层),它包含这些方法。

  • 创造
  • 修补
  • 删除
  • 得到一个
  • 获取列表

具有这些方法的此类是否违反了SRP

python
class UserService:

    repository: Repository

    def create(...):
        self.repository.save(...)

    def patch(...):
        self.repository.patch(...)

    def delete(...):
        self.repository.delete(...)

    def get_one(...):
        return self.repository.get(...)[0]

    def get_list(...):
        return self.repository.save(...)
Run Code Online (Sandbox Code Playgroud)

如果这有很多职责我该如何分配课程?

exp*_*ble 5

单一责任原则是一个棘手的原则。

让我们首先定义软件系统上下文中的责任以及该责任的范围。

责任有多种不同的形式。您认为的所有内容都可以是责任,代码中的所有内容都可以有责任。

  • 你的模块有责任。如果您有计费模块,则该模块负责处理计费。

  • 现在,如果您深入挖掘,您的计费模块可以包含多个层。每一层都有特定的职责。演示业务逻辑

  • 深入挖掘缩小范围,我们发现每一层都由不同的类和/或函数组成。他们每个人都可以承担一项责任。

  • 现在我们来看看函数和里面的代码。在那里你可以有多个语句 if、for、= 等。每个语句都在做一些责任。如果您分析您的语句,您会注意到函数/方法有多少职责。

如果你有UserRepository并且它唯一做的事情就是与数据库通信或在你的应用程序和 ORM 之间进行调解,那么它就有这个责任。这并不意味着您Repository将拥有单一方法。为了遵守 SRM,您UserRepository应该只有处理与users. 它不应该包含任何业务逻辑。

如果您有UserService且仅具有与用户相关的操作,则该服务遵守 SRP,因为它的责任是具有与 相关的操作Users

现在这是 SRP 中极其棘手的部分。

为了让你UserService完成它的工作,它需要调用UserRepository. 如果该服务创建用户然后将它们添加到数据库中,这是否意味着该服务UserService责任保存新用户

我们看到我们在这里有两项独特的责任。

  • 知道如何做一件事的责任。他们UserRepository知道如何与 ORM 或 DB 进行通信并保存新用户。

  • 当事情需要做的时候就说的责任。他们UserService知道应该何时User 保存,而不是如何或在哪里保存

您有两项不同的责任。如果您更改持久性,因为您将更改how 和/或 where,您只会更改 Repository 实现,但 Service 不会受到影响。如果您的业务逻辑发生变化,您会在 时发生变化,因此服务将发生变化,但存储库不会发生变化。

另一件事是当对象的接口变大时。

人们开始怀疑这个大接口是否遵守单一职责?

如果所有方法都具有凝聚力,那就可以了。这意味着某物的大小并不意味着它违反了 SRP。它可能违反其他原则,例如接口隔离原则,但这并不意味着它违反SRP。它只是很难使用、阅读、修改等。在这种情况下,你可以将它分解为多个较小的东西。

这是一个例子。假设您存储应用程序的设置。您可以设计一个ISettingsProvider具有所有设置属性的界面,并将生成一个具有 50 个方法的界面。如果我们将职责定义为保存设置,则该接口并不违反SRP。如果我们将责任定义为保存应用程序特定部分的设置,那么该接口将违反它。

上述示例的目的是表明,有时 SRP 可能是主观的,而粒度很重要。如果你用较小的范围来定义你的职责,那么为了遵守SRP,你将需要设计更小的接口、类的函数。

关于它作为树结构。顶部范围更宽,由更细粒度的范围等组成。根据您查看的位置,您的组件/对象/模块可能会遵守 SRP。

如果您在一个巨大的类中有一个Billing 模块,那么从系统的角度来看,该模块非常适合 SRP。从模块内部职责的角度来看,实现模块的类将具有业务逻辑、数据库通信代码、查询构建等,并且该类将违反SRP。