四种设计模式如何融入 MVC 范式?

Posted

技术标签:

【中文标题】四种设计模式如何融入 MVC 范式?【英文标题】:How do Gang of Four Design Patterns fit into the MVC paradigm? 【发布时间】:2012-02-25 12:57:39 【问题描述】:

我已经考虑 设计模式 有一段时间了,我才刚刚开始了解如何将其中一些更慎重地融入我的开发工作中。但是,我仍然对他们在本书开头对 MVC 的处理以及它与本书其余部分的关系感到困惑。

我使用过的大多数框架——Spring、Yii、ASP.NET,甚至 Objective-C Cocoa (UIKit)——都迎合了 MVC 范式。我得到 MVC 是因为对我来说它是一种有用的方式来分类对象以及它们应该如何相互发送消息或交互。此外,即使您不打算以 MVC 方式思考,这些框架也会对您施加压力。

我也觉得我理解设计模式的前提:他们真的不喜欢子类化,他们喜欢抽象接口,并且他们力求松耦合。我不能说我完全理解所有的模式或者它们是如何有用的,但我已经感觉到了。

我的问题是:MVC 和设计模式之间的相互作用是什么?他们在本书第一章的 MVC 应用程序示例中得到了什么?某些设计模式与 MVC 范式无关吗?例如,我想知道命令模式应该如何适应 MVC。它看起来非常有用,但是我们是否创建了一个 CommandModelCommandController 来发送给其他控制器?我们只是按照书中的规定创建一个Command 对象吗?基本上,我想知道 MVC 和 设计模式 的想法是否完全脱节,我只是不明白,或者是否有一些模式不适合模具。

【问题讨论】:

这可能是一个很好的阅读:***.com/questions/3148097/mvc-and-command-pattern 我认为第一部分(实际上是第 2 章)的重点是表明这些是在实际程序中使用的真实概念,而不仅仅是另一部来自象牙塔的崇高思想的学术著作。 【参考方案1】:

GoF 书中的 MVC 是针对桌面的,它使用观察者模式来更新视图。 GoF 书中的命令示例适用于编辑器。

还有其他风格的 MVC,其中其他设计模式的使用可能并不明显:What is the difference between MVC and MVVM?Presentation abstraction control

GoF 书说:

...

从表面上看,这个例子反映了一种将视图与模型分离的设计。但是该设计适用于更普遍的问题:解耦对象,以便对一个对象的更改可以影响任意数量的其他对象,而无需更改对象知道其他对象的详细信息。观察者(第 293 页)设计模式描述了这种更通用的设计。

MVC 的另一个特性是视图可以嵌套。例如,按钮的控制面板可以实现为包含嵌套按钮视图的复杂视图。对象检查器的用户界面可以包含可以在调试器中重用的嵌套视图。 MVC 通过 CompositeView 类(View 的子类)支持嵌套视图。 CompositeView 对象的行为就像 View 对象一样;复合视图可以在可以使用视图的任何地方使用,但它也包含和管理嵌套视图。

同样,我们可以将其视为一种设计,让我们可以像对待其中一个组件一样对待复合视图。但是该设计适用于更普遍的问题,每当我们想要对对象进行分组并将组视为单个对象时都会发生这种情况。这种更通用的设计由 Composite (163) 设计模式描述。它允许您创建一个类层次结构,其中一些子类定义原始对象(例如 Button),而其他类定义将原始对象组合成更复杂对象的复合对象 (CompositeView)。

MVC 还允许您更改视图响应用户输入的方式,而无需更改其视觉呈现。例如,您可能想要更改它对键盘的响应方式,或者让它使用弹出菜单而不是命令键。 MVC 将响应机制封装在一个 Controller 对象中。控制器有一个类层次结构,可以轻松创建一个新控制器作为现有控制器的变体。

视图使用 Controller 子类的实例来实现特定的响应策略;要实现不同的策略,只需用不同类型的控制器替换实例即可。甚至可以在运行时更改视图的控制器,让视图改变它响应用户输入的方式。例如,可以禁用视图,使其不接受输入,只需给它一个忽略输入事件的控制器。

视图-控制器关系是策略 (315) 设计模式的一个示例。策略是表示算法的对象。当您想要静态或动态替换算法时,当您有很多算法变体时,或者当算法具有要封装的复杂数据结构时,它非常有用。

MVC 使用其他设计模式,例如工厂方法 (107) 为视图指定默认控制器类,以及装饰器 (175) 为视图添加滚动。但是 MVC 中的主要关系是由观察者、组合和策略设计模式给出的。

...

【讨论】:

【参考方案2】:

MVC 是一种模式。但它只涵盖了 Web 应用程序的一小部分。与 MVC 一起使用的另一种常见模式是存储库。这些是更多的架构模式……它们的范围对整个项目的影响更大。

GOF 模式会在各处以小方式介绍自己。他们可以根据设计选择帮助构建 MVC 基础架构。例如,策略被大量使用,因此您可以插入不同的方式来执行“身份验证”等操作。

您不必按原样使用模式,它们甚至不必是完全相同的代码结构。它更多的是您在设计中采用的模式的设计原则/目标。

【讨论】:

【参考方案3】:

MVC 是一个architectural pattern。它非常适合其他设计模式,如命令模式。但是你不能仅仅因为它们存在并且它们被写在一本权威的书中而应用它们。当您遇到编程/设计问题并且有一种方法可以解决其他人发现并记录下来的问题时,您可以应用模式。解决问题的方法是一种模式。例如,您有一个将数据保存到数据库的应用程序。要保存的数据非常复杂:必须插入一些记录,更新一些记录,删除一些记录。步骤顺序很重要,因为要插入到一个表中的记录取决于要插入到另一个表中的记录。因此,必须使用database transaction。实现事务的一种可能方法是使用命令模式。这样做的方法在 Larman 的“Applying UML and Patterns”一书中有很好的解释(“使用模式设计持久性框架”一章,“使用命令模式设计事务”部分 - 向下滚动到第 556 页)。 PersistentObject 是那里的一个抽象模型类。所有其他模型类都对其进行了扩展。在该示例中,MVC 在 UI、应用程序和域层中实现,但命令在持久层中实现。这些模式有助于解决不同的问题,并且在该示例中它们是相互支持的。

【讨论】:

赞成,因为您明确声明 MVC 实际上是一种架构模式。【参考方案4】:

我个人认为MVC是观察者模式的简化版,观察者模式是中介者模式的简化版。

MVC:一个模型,一个视图,控制器管理它们之间的通信。

观察者模式:一个模型,多个视图(观察者/订阅者),发布者管理通信

中介者模式:几个不同的模型,几个视图,中介者管理它们之间的通信。

【讨论】:

我找到了你对这个问题的禅宗答案,我完全同意。 我不认为MVC中模型和视图之间存在1-1的关系。您可以轻松地为同一模型创建多个视图。至少在我看来,这是使用 MVC 的优势之一;具有同一模型的多个表示形式,这些表示形式与模型的一次更新同时更新。 @ThomasEizinger 但在这种情况下,你会发现观察者模式有什么不同(如果有的话)? 这个人 (peter.michaux.ca/maria) 例如声称 MVC 实际上是三种模式的组合:观察者、策略和组合。我对 Smalltalk(MVC 的起源)没有个人经验,但我认为将 MVC 描述为这三种模式的组合是合理的说法。 @ThomasEizinger 我会读到它,尽管我的第一反应是他错了。我在 MVC 中没有看到组合模式,但我会阅读更多内容以了解他的观点。感谢您的信息。

以上是关于四种设计模式如何融入 MVC 范式?的主要内容,如果未能解决你的问题,请参考以下文章

前端MVC变形记

前端开发 | 前端MVC变形记

前端MVC变形记

WEB前端MVC架构变形记

第659期前端MVC变形记

iOS 关于MVC和MVVM设计模式的那些事