6

SRP 负责人说:

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

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

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

4

4 回答 4

9

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

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

于 2013-07-23T11:04:04.470 回答
3

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

现在您的示例似乎很合理,您有一个连贯的类,所有方法都是相关的,该类的用户知道这是要用于订单的类。这对我来说似乎是一个单一的责任。

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

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

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

于 2013-07-23T11:15:22.010 回答
2

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

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

当我希望我的代码通过单个入口点使用第三方组件时,我最常使用 Facade。这方面的一个例子是反腐败层模式。然而,我通常会三思而后行地为我自己的代码创建外观,因为你很容易被它的便利所吸引,这会阻止你真正考虑对象之间的依赖关系。

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

于 2013-07-23T12:33:55.310 回答
0

是的,但是外观模式的主要目的是切换职责分类维度。

外观将子系统中的所有对象包装成一个对象,并提供多个公共方法作为接口。

子系统中的对象根据业务实体进行分类。但是门面的方法是根据用例分类的。

如果只涉及一个用例的组件导入外观,则外观的其他用例的方法对该组件也是可见的。也就是说,在组件看来,门面有多重职责。

因此,外观模式通常与Interface Segregation一起使用。

于 2022-02-26T08:30:14.660 回答