【问题标题】:Does the Facade pattern violate SRP?Facade 模式是否违反 SRP?
【发布时间】:2013-07-22 09:07:15
【问题描述】:

SRP 负责人说:

一个类或模块应该有一个,并且只有一个改变的理由

我有一些Facade 类作为我的服务层类。例如SaleService,它提供了一些方法例如SaveOrder()CancelOrder()CreateOrder()GetAllOrders()GetAllPlannedOrders(),...

我只是因为它们的概念关系才把它们放在一起。
使用这种方法使用此类可能有多个 change() 的原因是否违反 SRP?如果是,我该如何处理这个问题?

【问题讨论】:

    标签: design-patterns service-layer single-responsibility-principle conceptual facade


    【解决方案1】:

    SRP 是关于一个职责的实现细节的更改,这可能导致一个类被修改,即使该职责只是类的一小部分。

    Facade 不能以这种精确、更严重的方式违反 SRP,因为它只是一种表面反映——它不会在每次操作的内部发生变化时都发生变化。当其中一个操作的名称发生变化时,它可能会发生变化,这确实会导致一些脆弱性但没有什么可怕的,或者当我们想要通过 Facade 反映的操作被删除或添加时 - 但这有更多处理 Facade 选择公开的内容,这 实际上是它的实际责任。

    当我希望我的代码通过单个入口点使用第三方组件时,我最常使用 Facade。 Anti-Corruption Layer 模式就是一个例子。然而,我通常会三思而后行地为我自己的代码创建外观,因为它的便利性很容易让你信服,这会阻止你真正考虑对象之间的依赖关系。

    我不确定SaleService 在您的示例中是否真的是一个门面,因为服务通常不仅仅是重定向到某些业务行为(它们可以进行日志记录、授权、事务管理、协调对业务的多个调用等)

    【讨论】:

      【解决方案2】:

      外观模式本身并不违反 SRP。外观模式通常隐藏底层对象之间的复杂交互。在这种情况下,外观的“单一职责”是管理这些交互。只要这些交互没有改变,你的外观就没有理由改变。如果交互变得非常复杂,可能值得再次将外观的实现拆分为多个对象。

      如果我看你的例子,我不会觉得你真的在试图隐藏复杂性,所以在这里重新考虑外观模式的使用可能会很有趣。

      【讨论】:

      • 谢谢,你说“所以在这里重新考虑使用外观模式可能会很有趣”。你有什么建议?
      • 不幸的是,如果不了解您的系统,这很难说;一个好的起点是考虑为什么你认为你需要外观模式。使用一个有几个正当的理由。如果您的原因不是其中之一,那么您可能只是在增加系统的复杂性。
      【解决方案3】:

      我认为 SRP 的目的是识别一个类做得太多的情况,而更好的设计是拥有多个类。一个经典的例子:一个 ReportProducer 类,它做一些工作来组装数据和一些工作来格式化输出,可能应该有两个类:一个用于收集,一个用于格式化。这种方法的好处之一是灵活性:我们可以使用单个收集类和多个不同的格式化程序类。

      现在你的例子看起来很合理,你有一个连贯的类,所有的方法都是相关的,这个类的用户知道这是为了订单而去的类。这对我来说似乎是一项单一的责任。

      改变的原因是什么?在报告示例中,我们有两种完全不同的更改:可能是数据来自何处的更改,或者可能是所需的格式更改。在您的示例中,有人可能会争辩说还有多种可能的原因:订单的“形状”可能会改变,所需的界面可能会改变(例如,添加 queryCancelledOrders() 方法)您作为门面的后端可能会改变。但是,我不认为这些迹象表明您违反了 SRP:它们都与呈现用于操作订单的界面的任务有关。

      如果我们完全从字面上理解“改变的单一理由”,那么我不相信我们可以编写任何课程。我们总是有接口和实现,通常还有一些依赖类。其中任何一个都可能改变,所以我们总是有至少两个甚至三个改变的理由。

      而是想想“这个类的职责是什么?”不使用“AND”之类的词,能不能用句子来表达。不好:收集数据并格式化报告。

      【讨论】:

      • 谢谢,你觉得我的 SaleService 课程的好句子是什么?
      猜你喜欢
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 2013-04-28
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-17
      相关资源
      最近更新 更多