MVC:这是初始化&的正确顺序吗?调用MVC层 [英] MVC : Is this the correct sequence to initialize & invoke MVC layers

查看:84
本文介绍了MVC:这是初始化&的正确顺序吗?调用MVC层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习基于php MVC的网页开发.起初,我实际上只是将项目分解为模型,视图,控制器3类.但是在之前的评论的帮助下,我意识到这些不是类,而是相反,它们是层

I am trying to learn php MVC based webpage development.At first i literally thougt that it's just decoupling the project into 3 classes Model, View, Controller.But with help SO previous post comments, i realized that these are Not class but instead they are layers

// don't be confused my class/OOP style, it is just for conceptual purpose
Model.php Layer related code   
View.php Layer  related code   
Controller.php Layer related code   

User: index.php
//initiating model layer related things
$m = new Model;
// initiating Controller layer related things
$v = new Controller($m);
// initiating view layer related things
$c = new View($m, $c);

但是,Internet上有许多MVC示例,这些示例有时会引起混淆和冲突.例如,有人建议:控制器可以同时访问模型和模型.视图,其他建议视图都可以访问这两个视图.因此,请任何人检查我的代码序列以确保它确实遵循MVC模式.

However, there are many MVC example over internet which are confusing and conflicting sometime.For example some suggest: controller have the access of both model & view, where other suggest view have the access of both.So please anyone check my code sequence to ensure that it does follow the MVC pattern correctly.

推荐答案

在桌面应用程序的原始MVC模式(由Trygve Reenskaug在1979年提出)中,控制器更新模型,模型通知有关更改的视图,然后视图从中获取数据.此外,M,V&人们认为C组件与窗口中的单个控件(按钮,文本框,复选框等)相关.如果屏幕上有15个控件,则每个控件都有一个附加"的MVC.

In the original MVC pattern for the desktop apps (presented by Trygve Reenskaug in 1979), the controller updates the model, the model notifies the view about the changes, and then the view pulls its data from it. Also, the M, V & C components were thought as related to a single control in a window (a button, a textbox, a checkbox, etc). If you had 15 controls on screen, then each of them had an MVC "attached" to it.

在Web应用程序中,不存在通知步骤(从模型到视图).但是M,V& M之间的其余关系C组件得以维护.因此,在Web MVC中,控制器更新模型,然后视图从模型中提取其数据.而且,所有这三个组件都与网页有关,而不是与网页上的单个控件有关.

In the web applications, the notification step (from model to view) is not present. But the rest of the relations between the M, V & C components is maintained. So, in a web MVC, the controller updates the model and the view pulls its data from it. Also, all three components are related to a web page, not to a single control on it.

控制器和视图均不应使用域对象,例如实体(作为域模型的一部分).它们仅通过应用程序服务(也称为用例)与域模型进行通信(单独).这些服务可以将(多个)任务委派给(多个)域服务.依次使用域对象(实体).如果需要外部组件和/或服务(例如持久性层中的组件和/或服务,例如存储库,数据映射器),则可以通过使用相应的组件在域模型和它们之间建立连接.接口.这些也是域层的一部分.

Both, controller and view, should never use domain objects, e.g. entities (as part of the domain model) directly. They communicate (separately) with the domain model only through application services (also named use cases). These services may delegate (multiple) tasks to (multiple) domain services. Which, in turn make use of the domain objects (entities). If external components and/or services are needed (like the ones in the persistence layer, e.g. repositories, datamappers, for example), then the connection between the domain model and them is made through the use of corresponding interfaces. These also are part of the domain layer.

视图不应访问控制器.到底为什么要这样?控制器解释用户(通过HTTP协议,在Web应用程序中)发送的请求,并将所有与域相关的工作推迟到域中的服务层,并将请求数据传递给该服务层.因此,控制器仅在域层中影响更改.另一方面,该视图仅从域层请求数据.它也通过服务来做到这一点.因此,该视图从该域中读取.因此,在您的代码中,视图应仅接收$m作为参数.

The view should never access the controller. Why should it, at all? The controller interprets the request sent by the user (through the HTTP protocol, in web apps) and defers all the domain related work to the service layer in the domain, passing it the request data. So the controller only effects changes in the domain layer. On the other side, the view requests data only from the domain layer. It does this through services as well. So the view reads from the domain. Therefore, in your code, the view should receive only the $m as argument.

关于视图直接从域层提取数据有一个重要方面:如果视图希望简单地直接呈现从域接收的数据,则这意味着域将负责准备工作(视图的数据(例如格式化).但这意味着,模型应该知道准备数据的格式.例如.域模型将必须具有关于位于其边界之外的组件的知识.这样不好.因此,视图的作用是接收未经准备的数据,将其格式化为网页,然后进行呈现.总之,视图执行表示逻辑.

There is an important aspect regarding the view pulling data directly from the domain layer: If the view would expect to simply, directly present the data received from the domain, then this would mean that the domain would be responsible with the preparation (e.g. formatting) of the data for the view. But that would imply, that the model should know, in which format is to be the data prepared. E.g. the domain model would have to have knowledge about components residing outside its boundaries. This would not be good. So the role of the view is to receive unprepared data, to format it for the web page, and to present it. In a word, the view executes the presentation logic.

在下面的链接中,Robert C. Martin进行了精彩的演讲,内容涉及如何将应用程序所涉及的组件之间的关注点分离开来,从而形成一个良好的应用程序体系结构.将上述想法与演示文稿中提出的想法进行比较,您会发现它们之间存在两个区别.

In a link bellow is a great presentation by Robert C. Martin about how the concerns should be separated between the components involved in an application, resulting in a good application architecture. Making a parallel between the above ideas and the ones presented in the presentation, you will discover, that there are two differences between them.

第一个是,在视频中,演示层由演示者,视图模型和视图组成.而在上述的Web MVC中,整个表示逻辑仅由视图执行-效果不是很好.

The first one is, that, in the video, the presentation layer consists of a presenter, a view model and a view. Whereas in the web MVC described above, the whole presentation logic is performed only by the view - which is not so good.

第二个是,在视频中,表示层要处理和显示的数据从控制器通过域层到表示层被推送.现在想像一下自己,那个演示者取决于一个交互者(实际上是一个应用程序服务,一个用例).例如.从演示者指向域层的箭头描述的是 dependency 关系,而不是 inheritance 关系.然后,演示者的角色将拉出信息到域层之外.这样,与上面提供的Web MVC的类比就显而易见了.

The second one is, that, in the video, the data to be processed and displayed by the presentation layer is pushed from the controller through the domain layer to the presentation layer. Now try to imagine yourself, that that presenter depends on an interactor (which, actually is an application service, a use case). E.g. that the arrow pointing from the presenter to the domain layer describes a dependency relation, instead of an inheritance one. Then the role of the presenter will be to pull information out of the domain layer. The analogy with the web MVC presented above is then obvious.

资源:

主题演讲:迷失的年代的建筑-演示文稿由 Robert Martin 授权,并根据

Keynote: Architecture the Lost Years - Presentation given by Robert Martin, licensed under a Creative Commons Attribution ShareAlike 3.0.

示例1(在index.php中):显示数据

用户在浏览器的地址栏中引入URL http://localhost/questions/12345,并期望一个带有问题和多个注释的html页面.因此,HTTP方法为"GET".因此,不需要控制器,而只需一个视图(用于读取和显示域模型中的数据).

The user introduces the URL http://localhost/questions/12345 in the address bar of the browser and expects a html page with a question and multiple comments for it. Therefore the HTTP method is "GET". So no controller is needed, but only a view (for reading and displaying data from the domain model).

<?php

namespace Test\MvcExample;

use Lib\Http\Message\Response;
use Lib\Router\RouteCollection;
use Lib\Http\Message\ServerRequest;
use Lib\Http\MessageEmitter\ResponseEmitter;

/*
 * -----------------------------------------
 * Before dispatching by a front-controller.
 * -----------------------------------------
 */
$routes = new RouteCollection();
$routes->add('GET', '/questions/{id:\d+}', [
    'view' => [QuestionsView::class, 'index'],
]);

$request = new ServerRequest('GET', '/questions/12345' /* , other args */);
$response = new Response(/* args */);

/*
 * ------------------------------------------------------------------
 * Dispatched by a front-controller.
 * Route params are saved into the attributes list of server request.
 * ------------------------------------------------------------------
 */
$view = new QuestionsView(new Template(), new QuestionsService(), new CommentsService());

$response = $view->index($response, $request->getAttribute('id'));

/*
 * ----------------------------------------
 * After dispatching by a front-controller.
 * ----------------------------------------
 */
$responseEmitter = new ResponseEmitter();
$responseEmitter->emitResponse($response);

示例2(在index.php中):更新和显示数据

在URL http://localhost/questions/edit/12345上,用户以具有属性action="/questions/update"的形式编辑问题,然后单击提交按钮更新".因此,HTTP方法为"POST".因此,既需要控制器(用于更新模型层),也需要视图(用于从模型层读取和显示数据).

At URL http://localhost/questions/edit/12345 the user edits the question in a form with attribute action="/questions/update" and clicks the submit button "Update". Therefore the HTTP method is "POST". So both a controller (for updating the model layer) and a view (for reading and displaying data from the model layer) are needed.

不仅可以使用视图,还可以更改为其他要求.例如,要使用演示者和视图,都共享一个视图模型.

Instead of only using a view, one can change to other requirements. For example, to use a presenter and a view, both sharing a view-model.

<?php

namespace Test\MvcExample;

use Lib\Http\Message\Response;
use Lib\Router\RouteCollection;
use Lib\Http\Message\ServerRequest;
use Lib\Http\MessageEmitter\ResponseEmitter;

/*
 * -----------------------------------------
 * Before dispatching by a front-controller.
 * -----------------------------------------
 */
$routes = new RouteCollection();
$routes->add('POST', '/questions/update', [
    'controller' => [QuestionsController::class, 'updateQuestion'],
    'view' => [QuestionsView::class, 'getQuestionUpdated'],
]);

$request = new ServerRequest('POST', '/questions/update' /* , other args */);
$response = new Response(/* args */);

/*
 * ----------------------------------
 * Dispatched by a front-controller.
 * ----------------------------------
 */
$questionsService = new QuestionsService();

$controller = new QuestionsController($questionsService);
$controller->updateQuestion($request);

$view = new QuestionsView(new Template(), $questionsService);

$response = $view->getQuestionUpdated($response, $request);

/*
 * ----------------------------------------
 * After dispatching by a front-controller.
 * ----------------------------------------
 */
$responseEmitter = new ResponseEmitter();
$responseEmitter->emitResponse($response);

这篇关于MVC:这是初始化&amp;的正确顺序吗?调用MVC层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆