MVC 设计 - 有多少个控制器?

发布于 2024-10-31 21:47:37 字数 759 浏览 1 评论 0原文

概述

我正在构建一个简单的 Web 应用程序,由画布和画布上的元素组成。

画布支持以下操作:加载、保存

元素支持以下操作:移动、调整大小

网页上的 JavaScript 会针对每个操作向服务器发送一条消息,然后服务器发送相应的响应。

我的设计

在此处输入图像描述

注意:Canvas 和 Element 对象之间的箭头应该是表示 Canvas 对象包含 Element 对象的列表。我没有正确的图表符号。

示例工作流程

  1. 画布上的元素被移动,生成 element_moved 消息。
  2. 前端控制器管理会话并将消息传递到具有正确画布对象的画布控制器。
  3. 画布控制器检查该消息并发现它适用于画布上的元素,并将其传递给元素控制器。
  4. 元素控制器解析消息并直接更新适当的元素对象。

问题

这种控制器的分层排列在 MVC 设计中是否常见,还是我完全没有抓住要点?我已经搜索了几个小时,但没有找到任何比简单返回页面视图更深入地讨论 MVC 设计的网站。

我设计背后的动机是,客户端需要与之交互的每个对象都有一个控制器,这样,如果界面发生变化(以支持新方法),则可以更新相应的控制器,而不会影响设计的其他部分。

Overview

I’m building a simple web application consisting of a canvas and elements on the canvas.

The canvas supports the following operations: load, save

The elements support the following operations: move, resize

JavaScript on the web page sends a message to the server for each operation and the server sends an appropriate response.

My design

enter image description here

Note: the arrow between the Canvas and Element objects is supposed to denote that the Canvas object contains a list of Element objects. I didn't have the right symbols for the diagram.

Example work flow

  1. An element on the canvas is moved generating an element_moved message.
  2. The front controller manages the session and passes the message to the canvas controller with the correct canvas object.
  3. The canvas controller inspects the message and sees that it is for an element on the canvas and passes it on to the element controller.
  4. The element controller parses the message and updates the appropriate element object directly.

Question

Is this hierarchical arrangement of controllers common place in MVC designs or am I completely missing the point? I've searched for several hours but haven't found any sites which discuss MVC design in more depth than simply returning a page view.

My motivation behind the design was that each object that the client needs to interact with has a controller so that if the interface changes (to support new methods) then the corresponding controller can be updated without impacting the other parts of the design.

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

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

发布评论

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

评论(2

夏花。依旧 2024-11-07 21:47:37

通常,在 MVC 中不会有一个控制器调用另一个控制器。您指定的元素控制器实际上只是更新画布模型的业务逻辑的一部分。如果您的用例要求您独立于 Canvas 更新元素,那么您将有一个单独的元素控制器,调用业务逻辑来更新元素。

干杯,
瑞安

usually you won't have one controller calling another in MVC. What you have specified as Element Controller is really just a part of business logic to update the canvas model. If your use case requires you to update the elements independently of the Canvas, then you will have a separate Element Controller, calling the business logic to update the element.

Cheers,
Ryan

岁月打碎记忆 2024-11-07 21:47:37

在尝试组织 MVC 的客户端 JavaScript 中的问题时,您的情况引发了基本问题。


第一个基本问题

1) 是否应该整个“页面”使用一个整体Controller,其中此类Controller的成员方法是处理单个Model和单个模型的事件处理程序/起点code>View 整个页面?

用正则表达式来说...

Controller{1}

Model{1}

View{1}

由于只有一个Controller,因此其方法必须充当输入的事件处理程序/侦听器的想法没有歧义方案:Controller.moveCircle()

装傻一分钟,如果只有一个 Model,那么您可以简单地去一个地方创建您需要的所有数据/状态处理方法。正确的? (呵呵);-) Model.calculatePosition(), Model.calculatePrice()

在最基本的客户端/Web场景中,如果只有一个View,人们可能认为只需将所有表示逻辑放在那里就可以完成工作:View.repositionCircle(x, y)View.repositionTriangle(x, y)< /code>

讨论 1

为什么像这样的整体 ControllerModelView 方案在未来?

我可以将各个屏幕元素及其行为转移到其他“页面”,而不会有任何麻烦或额外的负担吗?

耦合和内聚

考虑耦合。整体控制器是否松散紧密耦合访问屏幕目标?

想想凝聚力。整体控制器对与访问单个目标相关的行为/方法进行分组是还是

Controller.moveCircleUp()Controller.moveTriangleUp() 会处理访问一个屏幕目标还是两个

在这种情况下,诸如有关整体控制器的广泛问题也适用于整体模型和视图。模型很可能由多个对象组成,用于执行和处理各种事物的数据/状态,因此通常不会对其位置产生混淆。

然而,如果它也是一个整体,那么它必须处理所有屏幕目标的数据/状态。即使在这样的模型中使用多个对象属性和多个方法,这也可能会变得混乱。

可重用性和可维护性

我在这里所写的内容对于代码的可重用性可维护性来说并不有利。即使您不是 SOLID 专家,也很容易理解为什么单体架构往往会违反单一职责原则。您不应该在同一位置更改圆形的某些内容,同时也对三角形进行更改。

为什么?这样想吧。船翻了之后,你漂浮在海里。这是你和另一名船员。你是否愿意紧密相连,这样如果他失去知觉,他或她也会把你拖倒?不,你会想要独立于船员,这样你就可以自由地自己下沉或游泳。

如果你们在臀部耦合,你们可能会撞到对方的脸,或者犯一些其他错误,而如果每个人都是一个漂浮者,则不会发生这些错误。

换句话说,独立运作并一起工作比齐心协力完成同样的事情要好。这与事情何时进展顺利无关。它是关于什么时候事情出错,或者什么时候独立更可取。例如,当一个人能够抓住直升机上悬挂的绳梯,但另一个人却被鲨鱼啃咬。

您希望能够在不同的屏幕或应用程序中重用应用程序元素。这就是为什么松耦合强内聚是面向对象编程和一般编程的基础。

(**注意:查看 并不意味着仅 HTML,即使这是最常见的最终结果。其他可能性包括 SVG、XML、Canvas 图形、图像格式...任何适合情况的内容。)

第二个基本问题

2) 屏幕上每个精心设计的可操作对象/元素/目标是否应该有自己的控制器模型视图

用正则表达式来说...

Controller+ (one or more)

Model+      (one or more)

View+       (one or more)

讨论 2

您想在其他页面/屏幕上使用屏幕目标/元素并带来它们的特定行为吗?

在第一个场景中,ControllerModelView 之间存在 1:1:1 关系。它们是整体的。有一个屏幕/网页。在这种设置中,您不能将一个放在另一个页面/屏幕上,而不带上三角形的逻辑!

如果目标是使代码在另一个上下文中可重用,那么答案是每个形状都需要一个独立的 MVC 安排。每个目标都有自己的ControllerModelView

实际上,这意味着您指定的每个屏幕元素都知道如何接受事件的输入、处理它并显示输出。不知何故,我们又回到了听起来相当基本的事情上。


最后的想法

如果人们接受上述内容为真,那么形状就是活生生的。 :-) 它们独立于上下文。操作它们不应该依赖于首先触发的一些包罗万象的JavaScript、FrontController、事件处理霸主,而只是将工作委托给目标的单个控制器的方法。

PHP MVC

服务器端 PHP 在到达所需的 Controller 子类之前使用 FrontController 方案,因为如果您有一个单点入口在应用程序 (/index.php) 中,您必须将 HTTP 请求 (/contact/send) 转换(路由)到 Controller 的实例,并从该控制器调用所需的方法:ContactController->send()

性能

这里真正的问题是,在下载所有 JavaScript 并将其加载到用户代理中后,应用程序的性能如何。

回答?你进行的操作越多,你使用的内存就越多。如果每个屏幕元素的 ControllerModelView 至少有三 (3) 个文件,则十个元素可能意味着三十个 (文件下载)至少。

当然,其他配置也是可能的,但这就是某种工具可能会派上用场来连接和缩小所有内容的地方。在 JavaScript 中,我宁愿为每个文件开发一个对象。

我希望这有帮助!

Your situation raises fundamental questions when attempting to organize concerns in client-side JavaScript for MVC.


First Fundamental Question

1) Should the entire "page" use one monolithic Controller, where member methods of such a Controller are the event handlers / starting points for working with a single Model and a single View for the entire page?

In regular expression speak ...

Controller{1}

Model{1}

View{1}

Since there is only ever one Controller, there is no ambiguity in the idea that its methods must serve as the event handlers / listeners for input into the scheme: Controller.moveCircle().

Playing dumb for a minute, if there is only ever one Model, then you can simply go to one place to create all the data / state handling methods that you need. Right? (hehehe) ;-) Model.calculatePosition(), Model.calculatePrice()

In the most basic client-side / web scenario, if there is only ever one View, one might think just putting all presentation logic there could get the job done: View.repositionCircle(x, y), View.repositionTriangle(x, y)

Discussion 1

Why might a monolithic Controller, Model, or View scheme like this be problematic in the future?

Can I transfer individual screen elements and their behaviors to other "pages" without any hassle or extra baggage?

Coupling and Cohesion

Think coupling. Does a monolithic Controller loosely or tightly couple accessing screen targets?

Think cohesion. Does a monolithic Controller group behaviors / methods related to accessing an individual target strongly or weakly?

Would Controller.moveCircleUp() and Controller.moveTriangleUp() be dealing with accessing one screen target, or two?

In this case, broad questions like these about a monolithic Controller would also apply to monolithic models and views. A Model is most likely composed of several objects for doing and dealing with the data / state of various things, so there's generally less confusion about it's place.

Yet, if it is a monolith too, then it must deal with the data / state of all screen targets. Even with using multiple object properties and multiple methods in such a model, that could get messy.

Re-usability and Maintainability

What I have written about here cannot be good for code re-usability and maintainability. Even if you are no SOLID expert, it is easy to understand why monoliths tend to violate the Single Responsibility Principle. You should not be in the same place to change something about a circle, where you also make changes for a triangle.

Why? Think of it this way. You are floating in the ocean after your boat capsizes. It is you and another crewman. Would you rather be joined at the hip, so that if he loses consciousness, he or she takes you down too? No, you would want to be independent of the crewman so that you are free to sink or swim on your own.

If you are coupled at the hip, you might hit each other in the face or make some other error that would not have happened if each was a single floater.

In other words, it is better to operate independently and work together, than it is to be joined at the hip and try to accomplish the same things. It is not about when things go well. It is about when thing go wrongly, or when independence is preferable. For example, when one is able to grab a rope ladder dangling from a helicopter, but the other is getting gnawed on by a shark.

You want to be able to reuse application elements in different screens or applications altogether. This is why loose coupling and strong cohesion are fundamental to object-oriented programming, and programming generally.

(**Note: View does not mean HTML only, even if this is the most common end result. Other possibilities include SVG, XML, Canvas graphics, image formats ... anything that fits the circumstance.)

Second Fundamental Question

2) Should each crafted, actionable object / element / target on the screen have its own Controller, Model, and View?

In regular expression speak ...

Controller+ (one or more)

Model+      (one or more)

View+       (one or more)

Discussion 2

Do you want to use screen targets / elements on other pages / screens and bring their specific behaviors with them?

In the first scenario, there is a 1:1:1 relationship between Controller, Model, and View. They are monolithic. There is one screen / webpage. In that setup, you cannot take a circle and put it on another page / screen without bringing along the logic for triangle, too!

If the goal is to make code reusable in another context, then the answer is that each shape requires a self-contained MVC arrangement. Each target would have its own Controller, Model, and View.

In effect, this would mean each screen element that you designate worthy would know how to accept input from an event, process it, and show the output. Some how, we made it back to something that sounds rather fundamental.


Final Thoughts

If one accepts the the above as true, then shapes are, well, alive. :-) They are independent of the context. Manipulating them should not depend on the some all encompassing, JavaScript, FrontController, event handling overlord to be triggered first, only to delegate the work to a method of the target's individual Controller.

PHP MVC

Server-side PHP uses the FrontController scheme before getting to the desired Controller sub-class because if you have a single point of entry into the application (/index.php), you have to translate (route) the HTTP request (/contact/send) into an instance of a Controller, and call the desired method from that controller: ContactController->send().

Performance

The real issue here is how well will the application perform after having downloaded and loaded all of the JavaScript into a user-agent.

Answer? The more you have going on, the more memory you will use. If each screen element has a minimum of three (3) files for its Controller, Model, and View, then ten elements could mean thirty (files to download) at minimum.

Of course, other configurations are possible, but that is where a tool of some sort might come into handy to concatenate and minify everything. In JavaScript, I would rather develop one object per file.

I hope this helps!

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