该课程是否违反单一责任原则?

时间:2019-04-20 07:50:40

标签: python solid-principles single-responsibility-principle

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

  • 创建
  • 补丁
  • 删除
  • get_one
  • get_list

使用这些方法的此类是否违反了SRP?

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(...)

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

1 个答案:

答案 0 :(得分:1)

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

让我们开始定义在软件系统的上下文中什么是责任以及该责任的范围。

责任有许多不同的形式。您认为的一切都可以成为责任,代码中的所有内容都可以担负责任。

  • 您的模块有责任。如果您有 Billing模块 ,则此模块负责处理Billing。

  • 现在,如果您进行更深入的研究, 计费模块 可以包含多个层次。每层都有特定的责任。 演示文稿 业务逻辑

  • 通过深入挖掘来缩小范围,我们发现每一层都由不同的类和/或功能组成。他们每个人都有责任。

  • 现在我们进入函数和内部代码。在这里,可以有多个语句,例如for = =等。每个语句都在做某事。如果分析您的陈述,您会注意到功能/方法有多少职责。

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

如果您拥有UserService,并且仅具有与用户相关的操作,则该服务会遵循SRP,因为它的职责是拥有与Users相关的操作。

现在,这是SRP中非常棘手的部分。

为使您的UserService能够完成工作,需要调用UserRepository。如果此服务创建了用户,然后将其添加到数据库中,这是否意味着UserService具有保存新用户的责任

我们看到我们在这里有两个独特的职责。

  • 知道如何做某事的责任。 UserRepository知道如何与ORM或数据库进行通信并保存新用户。

  • 陈述何时需要做某事的责任。 UserService知道User的保存时间 ,而不是保存方​​式或保存位置

您有两个不同的职责。如果您更改持久性,因为您将更改方式和/或位置,则仅更改存储库实现,但服务不会受到影响。如果您的业务逻辑发生更改,则您更改时间,因此服务将更改,但存储库将更改。

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

人们开始怀疑这种大型界面是否只遵循单一责任?

如果所有方法都具有凝聚力,则可以。这意味着某事物的大小并不意味着它违反了SRP。它可能违反了Interface Segregation Principle之类的其他原则,但这并不意味着它违反了SRP。很难使用,阅读,修改等。在这种情况下,您可以将其分解为多个较小的内容。

这是一个例子。假设您存储应用程序的设置。您可以设计一个具有所有设置属性的界面ISettingsProvider,该界面将导致具有50种方法的界面。如果我们将职责定义为<保存设置,则此界面不会违反SRP。如果我们将职责定义为保存应用程序特定部分的设置,则此界面将违反它。

上面的示例旨在说明有时SRP可能是主观的,并且粒度很重要。如果您以较小的范围来定义职责,那么为了遵守SRP,您将需要设计较小的接口,类的功能。

关于它的树状结构。顶级范围更广,由更细粒度的范围组成,依此类推。根据您的外观,您的组件/对象/模块可能会遵循SRP。

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