比MVC更适合Web应用程序的架构是什么?

51

我正在学习Zend及其MVC应用程序结构以适应我的新工作,但我发现使用它让我感到困扰,原因我无法具体说出。在学习过程中,我发现了一些文章,例如MVC: No Silver Bullet这个播客,关于MVC和Web应用程序的主题。播客中的人很好地反驳了MVC作为Web应用程序架构的优点,并且切中了我所纠结的问题。

然而,问题仍然存在:如果MVC并不是Web应用程序的好选择,那么什么是好的选择呢?


21
可以简要说明一下该播客所说的MVC有什么问题,这样读者就不必听节目也可以了解基本的反对意见。我也很感兴趣 :) - halfer
播客链接已经无法修复(wayback机器中没有任何内容)。它已被此页面替换,但那里的播客链接也已经失效。然而,如果您搜索“为什么MVC不是应用程序架构”的讲话,您可以找到同一人的这个视频演示 - icc97
4个回答

105
这完全取决于你的编程风格。这是个秘密:在PHP中不可能写出经典的MVC。任何声称可以的框架都是在骗你。事实上,框架本身甚至不能实现MVC——只有你的代码可以。但这可能不是一个很好的营销手段。
要实现经典的MVC,首先需要具有持久的模型,此外,模型应通知视图有关更改的信息(观察者模式),但是在您的普通PHP页面中这也是不可能的(如果使用套接字,则可以做到接近经典的MVC,但对于真正的网站来说这是不切实际的)。
在Web开发中,实际上还有其他4种基于MVC的解决方案:
  • Model2 MVC: 视图从模型请求数据,然后决定如何呈现它以及使用哪些模板。控制器负责更改视图和模型的状态。

  • MVVM: 控制器被 ViewModel 替换,ViewModel 负责在视图期望和模型逻辑之间进行翻译。视图请求控制器的数据,控制器将请求翻译成模型可以理解的形式。

    通常情况下,当您对视图或模型层都没有控制权时,会使用此方法。

  • MVP(PHP 框架称之为“MVC”):Presenter 从模型请求信息,收集、修改并将其传递给被动视图。

    要了解这种模式,我建议您先阅读 this publication。它会详细解释。

  • HMVC(或 PAC):与 Model2 不同,控制器具有执行子控制器的能力。每个子控制器都有自己的 M、V 和 C 三元组。您可以获得模块化和可维护性,但需要付出一些性能代价。

无论如何,最重要的是:您实际上并没有使用 MVC。

但是,如果您已经厌倦了所有类似于 MVC 的结构,可以尝试以下内容:

  • 事件驱动架构
  • n-Tier 架构

然后,总会有DCI范例,但在应用于PHP时存在一些问题(你不能将PHP转换为类..除非使用丑陋的黑客手段)。


1
谢谢,这些看起来很有趣。尤其是Model2。我会研究一下,看看哪个最适合我想要做的事情。 - GordonM
1
"要实现经典的MVC,首先需要具有持久的模型。"这句话是什么意思?“Persistent”是指不变的、重复的还是没有任何改变的?它是否暗示着“没有副作用的模型”或者完全不同的东西? - hhh
7
在经典的MVC模式中,视图观察模型(或者说是来自模型层的结构)。当模型状态改变时,视图请求新的信息。所谓的“持久化模型”,指的是模型层在应用程序的整个使用期间都存在。但在PHP中这是不可能的,因为当你发送响应时,模型层的实例会被销毁。这是PHP“无共享状态”架构的限制。因此,视图无法观察模型层,因为没有留下可供观察的内容。 - tereško
2
顺便提一下:有(或多或少)复杂的解决方案可以在php中启用持久会话,从而允许我们创建持久模型。这是我熟悉的解决方案:http://us2.php.net/manual/en/intro.memcache.php - Philipp
@tereško - 很抱歉打扰了一个两年前的问题,但是当我阅读时,我对前端控制器模式和model2 MVC之间的区别感到困惑。 (+1,总是详细解释) - mamdouh alramadan
显示剩余2条评论

5
从我的经验来看,采用MVC架构带来的好处远远超过为Web开发而付出的成本和明显的额外工作量。
对于那些初次接触复杂的MVC框架的人来说,将三个层次分离并确定每个部分所属可能会有点令人生畏(有些事情很明显,另一些可能比较模糊,需要进行讨论)。我认为这种成本在长期内可以得到回报,特别是如果您预计应用程序会增长或需要在相当长的时间内维护。
我曾经遇到过这样的情况:由于层次分明,创建新API以允许其他客户端连接到现有Web应用程序的成本非常低:业务逻辑与表示完全没有关联,所以一切都很轻松。
在当前的MVC框架生态系统中,我认为您可能会遇到差异很大的情况,因为原则是通用的,但是例如Zend,Django,RoR和SpringMVC之间存在许多差异。
如果确实有其他好的选择范式...... 我会非常感兴趣听听答案!
抱歉文字有点长!

1
我完全赞成模块化,但正如播客中所指出的那样,MVC似乎不是正确的方法。 "视图"旨在成为用户界面中的单个显示元素,而不是整个用户界面。 此外,在Zend中,整个系统似乎过于依赖魔法 - 很难知道程序流控制将跳转到哪里,除非使用XDebug或类似工具手动跟踪。 但这可能只是Zend大量使用单例和注册表的产物。 - GordonM

0

这完全是个人喜好。我曾经使用过像XTemplates和Smarty这样的旧结构,现在转向了Codeigniter和Kohona。我非常喜欢它们,并且它们对我在Web上所做的一切都非常有效。对于手机应用程序,我可以为需要执行其数据提取的功能设置控制器。在Linux世界和Windows世界中工作,对于构建ASP.NET网站,我认为除了使用MVC之外别无选择。Visual Studio中的Web应用程序项目仍在使用,但我不再喜欢使用它们。通过Visual Studio的MVC项目非常易于使用和设置。您可以右键单击控制器方法并自动创建视图。在每个结构中都有好坏之分,但开发人员可以根据自己的需求使用任何东西。


0

我认为这取决于你个人想要做什么。Magenta相当成功地使用了MVC,这使得添加新功能或修改现有功能变得相当容易。

当然,如果你想要制作一些相对简单的东西,采用MVC架构可能会过度设计。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接