我的MVC组件真的都需要相互引用吗?

时间:2012-06-14 08:54:59

标签: php model-view-controller

我正在使用PHP中的MVC。我没有使用框架,我只是想了解模式。

有时我会看到控制器,例如在这个tutorial中,用模型和视图实例化传递给构造函数,在同一个教程中,视图(这里是'模板')类接受一个控制器构造!

所以我的问题是:

  1. 为什么视图需要引用其控制器?这种关系中的观点不应该是被动的伙伴吗?
  2. 控制器是否应该对特定型号有内部参考?换句话说,为什么不在控制器操作中实例化模型并以这种方式使用它们呢?

5 个答案:

答案 0 :(得分:9)

鉴于MVC在网络上存在许多变化和误解,我投票决定将问题视为非建设性。由于评论范围有限,我将此答案作为社区Wiki提供。

enter image description here

MVC was originally conceived by Trygve Reenskaug for Desktop Environments而不是网络。我们现在看到的主要是某些形式的原始模式的变体,如MVP,HMVC,Model2-MVC等。他们的实现彼此不同,人们花了很多时间来讨论“MVC”究竟是什么或者应该如何实现。

enter image description here

就个人而言,我更喜欢Patterns of Enterprise Application Architecture definition of MVC,它说MVC 将用户界面交互分成三个不同的角色,因为这个定义没有实现的概念。

在书中,福勒指出,最重要的区别是模型与控制器和视图的分离。虽然本书确实涵盖了角色之间的关联,但我认为重点是要理解并关注角色而不是实现。

设计模式是蓝图,而不是详细的原理图。此外,MVC是一种模式语言。它的目标是为项目添加结构/表单。了解角色的用途,然后提出适用于您的项目的实现。

enter image description here

Fowler还有一个冗长的article on GUI architectures covering MVC详细解释了关联和依赖关系,以防你没有这本书。

  

图片/幻灯片:Architecture the Lost Years (Robert Cecil Martin; 4 Nov 2011)

答案 1 :(得分:3)

  1. 如果您有用户输入,您需要知道将它们发送到哪个..到哪个控制器。

  2. 我不喜欢我的控制器直接使用模型,因为控制器暴露在“外部世界”,容易受到攻击。 您可以查看服务层模式,数据传输对象模式等。 我喜欢将我的模型隔离在控制器将使用的服务API之后。 如果你需要一本关于模式的好书,你可以找到Martin Fowler的:)

答案 2 :(得分:1)

  1. 视图不应该引用控制器(当然不是动作链接)。控制器执行告知的操作并将结果发送到视图。

  2. 就我使用MVC而言,我在动作中实例化模型并以这种方式使用它。我不喜欢让我的控制器绑定到模型。通常我使用存储库结构来访问我的模型。在较大的项目中,我在控制器和模型之间有一个服务层。在.net MVC中,我开始使用viewmodels作为应用程序的控制器和MVC部分的实体,而我的服务处理与我的域模型有关的任何事情并返回视图模型。

答案 3 :(得分:1)

由于我已经managed在MVC和PHP的上下文中广泛地撰写关于模型的内容,所以我们只关注三元组的ViewController部分。

正如@Gordon已经提到的那样,我们在网上做的是不是经典的MVC 。这不是可能的反弹。相反,我们提出了原始想法的distinct变体。

视图不是模板

除非您使用特别糟糕的MVP实现,否则view实例是对象,负责表示逻辑。

controller实例是否需要访问view取决于您使用的MVC模式。在MVP和MVVM模式中controller实例从model layer请求信息并将其传递给view(通过一些修改或其他标志)。

在Model2模式(稍微接近原始概念)中,view实例本身能够从model layer中提取信息。在这种情况下,controller实例无需访问它。

控制器负责什么?

controller的实例不应直接从model layer实例化结构。主要原因有两个:

  • 导致与特定类名的紧密耦合,使得更难以进行测试和维护
  • 增加了额外的责任(或理由改变),因而违反了SRP

model layer的结构初始化很复杂。它们通常要求您从model layer注入数据库连接,缓存处理程序甚至其他结构。此任务应留给控制器使用的单独的类似工厂的实例(在controllerview实例之间共享)。

controller实例的主要职责应该是更改model layer的状态。它应该从用户那里获取输入,并在表单中进行翻译,model layer可以理解。

请注意,model layer作为一个整体必须完全无知关于viewcontroller个实例。

答案 4 :(得分:1)

根据我的经验,对MVC的确切含义有很多解释。几乎每个人都同意这一点:

  • 模型实现业务逻辑,并封装数据访问。
  • 视图实现表示逻辑。
  • 控制器处理输入和控制流程。

他们如何联系并彼此交谈是一个辩论,争论,拳击和圣战的问题。

实际上,控制器通常会加载视图和模型,视图有时会加载模型和控制器,但模型通常不会加载控制器或视图。

为什么视图会加载控制器?假设您实现了一个具有自己的控制器,模型和视图的小部件。您希望在多个位置的多个页面上加载此小组件。最简单的方法是在视图中加载小部件的控制器。

为什么视图会加载模型?也许您编写了控制器,因此可以加载两个或更多视图,并且您不希望为每个非常不同的视图加载不同的模型。所以你只需告诉每个视图加载它自己的模型。

分离角色,但允许最有效的交互,并在逻辑上实现您需要的系统。