MVC 中控制器的传统使用是否会导致违反单一职责原则?

发布于 2024-08-30 10:20:38 字数 361 浏览 10 评论 0原文

维基百科这样描述单一责任原则

单一职责原则规定每个对象都应该有单一的职责,并且该职责应该完全由类封装。其所有服务都应与该职责紧密结合。

MVC 中控制器的传统使用似乎导致程序员违反了这一原则。采用一个简单的留言簿控制器并进行查看。控制器可能有两种方法/操作:1) Index() 和 2) Submit()。 Index() 显示表单。 Submit() 处理它。这两种方法代表两种不同的职责吗?如果是这样,单一责任如何发挥作用?

Wikipedia describes the Single Responsibility Principle this way:

The Single Responsibility Principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.

The traditional use of the controller in MVC seems to lead a programmer towards a violation of this principle. Take a simple guest book controller and view. The controller might have two methods/actions: 1) Index() and 2) Submit(). The Index() displays the form. The Submit() processes it. Do these two methods represent two distinct responsibilities? If so, how does Single Responsibility come in to play?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

归属感 2024-09-06 10:20:38

是的,确实如此。

如果您想遵循 SRP,则可以将控制器分解为调度程序和操作;调度程序将控制调度到其操作,并且在编译时(C++ 模板)或运行时(Java XML,等等),您可以组合调度程序和操作。

为什么我们不经常看到这种情况?因为控制器通常是“临时”实现,所以叶级具体类不是通用的,也不意味着要进行子类化。在这里,类更多地用于方便地对代码进行分组,这些操作几乎肯定是非公共的(可能是私有的,可能是受保护的),“仅仅是”内部实现细节。

如何决定调度到哪个操作、可能的操作的数量和多样性的选择很高,并且调度和操作紧密耦合。因此,在实践中,将代码放在一处通常会更容易。

Yes it does.

And if you want to follow the SRP, you disaggregate your Controller into a Dispatcher and Actions; the Dispatcher dispatches control to its actions, and at compile-time (C++ templates) or at runtime (Java XML, whatever), you'd compose Dispatchers and Actions.

Why don't we see this more often? Because Controllers are often "ad hoc" implementations, leaf-level concrete classes that aren't generalized and aren't meant to be subclassed. Here, the class is used more to conveniently group code, the actions are almost certainly non-public (likely private, maybe protected), "merely" internal implementation details.

The choice of how to decide what action to dispatch to, the number and diversity of possible actions, is high, and dispatching and action are tightly-coupled. So in practice, it's often easier to just put the code together in one place.

奈何桥上唱咆哮 2024-09-06 10:20:38

不,事实并非如此。

MVC 模式或其变体没有任何固有的内容会导致违反单一职责原则。控制器的实现是否违反 SRP 取决于封装的行为是否有多个更改原因(就像任何其他类一样),而不是因为模式的任何预设规定使用。

您提出的示例是数据应用程序的基本形式的子集,其中控制器仅为给定模型提供 CRUD 操作。 CRUD 操作本质上是相当内聚的,因此这通常不构成违反 SRP。当单个控制器上的多个方法代表跨域的不同行为交互时,这些方法开始变得可疑。

也就是说,即使有人认为 CRUD 代表四个独立的非内聚关注点,MVC 模式也没有任何固有的东西迫使您在同一个控制器中促进这些操作中的每一个。

有关 MVC 模式的一些历史及其在 Web 开发中的应用的一些讨论,请查看 交互式应用程序架构模式

No, it doesn't.

There is nothing inherent to the MVC pattern or its variations which lead to a violation of the Single Responsibility Principle. Whether the implementation of a controller violates SRP or not is based upon whether the encapsulated behavior has more than one reason to change (just as any other class), not because of any presupposed prescriptive use of the pattern.

The example you set forth is a subset of a basic forms over data application, where the controller is merely providing CRUD operations for a given model. CRUD operations are fairly cohesive in nature, so this generally doesn't constitute a violation of SRP. Where having multiple methods on a single controller start to become suspect is when the methods represent different behavioral interactions across the domain.

That said, even if someone where to argue that CRUD represents four separate non-cohesive concerns, there is nothing inherent to the MVC pattern that forces you to facilitate each of these actions within the same controller.

For a little history on the MVC pattern as well as some discussion of its application in Web development, checkout Interactive Application Architecture Patterns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文