MVC 设计 - 有多少个控制器?
概述
我正在构建一个简单的 Web 应用程序,由画布和画布上的元素组成。
画布支持以下操作:加载、保存
元素支持以下操作:移动、调整大小
网页上的 JavaScript 会针对每个操作向服务器发送一条消息,然后服务器发送相应的响应。
我的设计
注意:Canvas 和 Element 对象之间的箭头应该是表示 Canvas 对象包含 Element 对象的列表。我没有正确的图表符号。
示例工作流程
- 画布上的元素被移动,生成 element_moved 消息。
- 前端控制器管理会话并将消息传递到具有正确画布对象的画布控制器。
- 画布控制器检查该消息并发现它适用于画布上的元素,并将其传递给元素控制器。
- 元素控制器解析消息并直接更新适当的元素对象。
问题
这种控制器的分层排列在 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
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
- An element on the canvas is moved generating an element_moved message.
- The front controller manages the session and passes the message to the canvas controller with the correct canvas object.
- 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.
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,在 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
在尝试组织 MVC 的客户端 JavaScript 中的问题时,您的情况引发了基本问题。
第一个基本问题
1) 是否应该整个“页面”使用一个整体
Controller
,其中此类Controller
的成员方法是处理单个Model
和单个模型的事件处理程序/起点code>View
整个页面?用正则表达式来说...
由于只有一个
Controller
,因此其方法必须充当输入的事件处理程序/侦听器的想法没有歧义方案:Controller.moveCircle()
。装傻一分钟,如果只有一个
Model
,那么您可以简单地去一个地方创建您需要的所有数据/状态处理方法。正确的? (呵呵);-)Model.calculatePosition()
,Model.calculatePrice()
在最基本的客户端/Web场景中,如果只有一个
View
,人们可能认为只需将所有表示逻辑放在那里就可以完成工作:View.repositionCircle(x, y)
、View.repositionTriangle(x, y)< /code>
讨论 1
为什么像这样的整体
Controller
、Model
或View
方案在未来?我可以将各个屏幕元素及其行为转移到其他“页面”,而不会有任何麻烦或额外的负担吗?
耦合和内聚
考虑耦合。整体
控制器
是否松散或紧密耦合访问屏幕目标?想想凝聚力。整体
控制器
对与访问单个目标相关的行为/方法进行分组是强还是弱?Controller.moveCircleUp()
和Controller.moveTriangleUp()
会处理访问一个屏幕目标还是两个 ?在这种情况下,诸如有关整体控制器的广泛问题也适用于整体模型和视图。模型很可能由多个对象组成,用于执行和处理各种事物的数据/状态,因此通常不会对其位置产生混淆。
然而,如果它也是一个整体,那么它必须处理所有屏幕目标的数据/状态。即使在这样的模型中使用多个对象属性和多个方法,这也可能会变得混乱。
可重用性和可维护性
我在这里所写的内容对于代码的可重用性和可维护性来说并不有利。即使您不是 SOLID 专家,也很容易理解为什么单体架构往往会违反单一职责原则。您不应该在同一位置更改圆形的某些内容,同时也对三角形进行更改。
为什么?这样想吧。船翻了之后,你漂浮在海里。这是你和另一名船员。你是否愿意紧密相连,这样如果他失去知觉,他或她也会把你拖倒?不,你会想要独立于船员,这样你就可以自由地自己下沉或游泳。
如果你们在臀部耦合,你们可能会撞到对方的脸,或者犯一些其他错误,而如果每个人都是一个漂浮者,则不会发生这些错误。
换句话说,独立运作并一起工作比齐心协力完成同样的事情要好。这与事情何时进展顺利无关。它是关于什么时候事情出错,或者什么时候独立更可取。例如,当一个人能够抓住直升机上悬挂的绳梯,但另一个人却被鲨鱼啃咬。
您希望能够在不同的屏幕或应用程序中重用应用程序元素。这就是为什么松耦合和强内聚是面向对象编程和一般编程的基础。
(**注意:
查看
并不意味着仅 HTML,即使这是最常见的最终结果。其他可能性包括 SVG、XML、Canvas 图形、图像格式...任何适合情况的内容。)第二个基本问题
2) 屏幕上每个精心设计的可操作对象/元素/目标是否应该有自己的
控制器
、模型
和视图
?用正则表达式来说...
讨论 2
您想在其他页面/屏幕上使用屏幕目标/元素并带来它们的特定行为吗?
在第一个场景中,
Controller
、Model
和View
之间存在 1:1:1 关系。它们是整体的。有一个屏幕/网页。在这种设置中,您不能将一个圆放在另一个页面/屏幕上,而不带上三角形的逻辑!如果目标是使代码在另一个上下文中可重用,那么答案是每个形状都需要一个独立的 MVC 安排。每个目标都有自己的
Controller
、Model
和View
。实际上,这意味着您指定的每个屏幕元素都知道如何接受事件的输入、处理它并显示输出。不知何故,我们又回到了听起来相当基本的事情上。
最后的想法
如果人们接受上述内容为真,那么形状就是活生生的。 :-) 它们独立于上下文。操作它们不应该依赖于首先触发的一些包罗万象的JavaScript、FrontController、事件处理霸主,而只是将工作委托给目标的单个控制器的方法。
PHP MVC
服务器端 PHP 在到达所需的
Controller
子类之前使用FrontController
方案,因为如果您有一个单点入口在应用程序 (/index.php) 中,您必须将 HTTP 请求 (/contact/send) 转换(路由)到Controller
的实例,并从该控制器调用所需的方法:ContactController->send()
。性能
这里真正的问题是,在下载所有 JavaScript 并将其加载到用户代理中后,应用程序的性能如何。
回答?你进行的操作越多,你使用的内存就越多。如果每个屏幕元素的
Controller
、Model
和View
至少有三 (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 aController
are the event handlers / starting points for working with a singleModel
and a singleView
for the entire page?In regular expression speak ...
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
, orView
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()
andController.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. AModel
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
, andView
?In regular expression speak ...
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
, andView
. 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
, andView
.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 individualController
.PHP MVC
Server-side PHP uses the
FrontController
scheme before getting to the desiredController
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 aController
, 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
, andView
, 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!