正确的Model-View -_____设计


14

我一直在阅读有关Model View Controller,Model View Presenter,Model View ViewModel等的内容,通常,基本概念似乎很容易理解:将漂亮的视觉效果和科学胆量保持彼此独立和无知,例如可能。设计巧克力中没有添加逻辑花生酱;酷,我喜欢。

问题是我对于第三部分还是有点模糊,不是模型或视图。每个人似乎都有自己的主意,如何称呼它,应该做什么,什么是正确的,什么是明显的错误……而且我很想弄清楚什么时候Presenter成为ViewModel,什么时候应该让View成为现实。不要这样做,因为那是主持人的工作,并且-

我在乱逛

而不是请别人解释它们之间的区别-因为已经一次又一次地做到了(我知道;我读了不计其数的文章)-我很好奇听到我自己拼凑的模型很少有程序员。

就是说,您会将此设计归类为什么?也许更重要的是,您是否对此有明显的印象?当然,如果这确实是可靠的设计,我很想听到我做的很好,但是我宁愿得到可靠的建议而不是赞美。

注意:我将使用“桥梁”作为Model-View-?的神秘第三部分。避免对其“应该”有任何潜意识的建议。

模型

  • 是对数据的授权。
  • 从网桥接收有关请求的更改的信息。
  • 包含并执行关于数据如何与其他数据相关的所有逻辑。
  • 数据更改时通知网桥(对于网桥表示感兴趣的数据)。文字编辑:允许外部订户(对其一无所知)监视其状态或计算结果。
  • 对视图的知识为零。

视图

  • 与为用户提供查看和操纵数据的方式有关。
  • 从网桥接收有关数据更新的信息。
  • 包含并执行有关如何向用户呈现数据和控件的所有逻辑。
  • 当用户执行了(可能)影响模型的操作时,通知Bridge。
  • 通知Bridge感兴趣的信息。
  • 对模型的知识为零。

  • 是模型和视图之间的协调者和翻译者。
  • 对在模型和视图之间传递的信息进行适当的格式更改。
  • 保留有关“谁需要知道什么”的信息。
  • 具有模型和视图的知识。

补充说明

  • 在更复杂的程序中,通常会有多个模型。在这种情况下,网桥通常承担在多个模型之间进行协调/转换的工作,因此成为应将原型/ API /设计模型构建到哪个模型的权限。(例如,如果构建纸牌游戏程序,并且您要构建备用的甲板改组模型,则应使用Bridge来确定与Bridge正确通信所需的功能。)
  • 在只有一个视图和模型的小型简单程序中,网桥通常会“假定”任一侧都有哪些功能。但是,随着程序变得越来越复杂,建议视图和模型向Bridge报告其功能,这样可以避免效率低下和错误的假设。

我认为这几乎涵盖了它。无论如何,我欢迎您对我倾向于使用的设计有任何疑问,并且我也鼓励您提出任何建议。

和往常一样,感谢您的宝贵时间。


2
View块具有复制粘贴错误。我猜最后一个项目符号应显示为“该模型的知识为零”。第一个附加说明的最后一句应该以“模型”而不是“桥梁”结尾?
Johannes S.

Answers:


7

你的话

“是模型和视图之间的协调器和转换器。”

表示您的网桥是MVP架构中的Presenter。

MVP和MVC非常相似,不同之处在于,在MVP中,只有演示者观察模型,而在MVC中,还允许视图直接观察模型(演示者不作为“桥梁”)。

您的模特责任

“在数据更改时通知Bridge(对于Bridge表示感兴趣的数据)。”

可能是措辞不佳或错误:您不希望模型依赖于Bridge / Presenter / Controller或View。相反,您可以使用观察者模式,事件或响应式编程来允许网桥订阅模型中的更改。然后,您可以将您的责任改写为:

“允许外部订户(对此一无所知)监视其状态或计算结果。”

如果您的模型不依赖于Controller或View,则测试起来更容易,移植性也更强。


1
如果关键的区别在于View是否可以观察模型,则设计绝对是MVP;视图和模型永远不能在我一直使用的设计中直接说出来。
KoratDragonDen 2014年

我认为,模型责任的措辞很差。该模型并没有真正的线索或关心要听它的事物的谁/什么/为什么,而只是发布对订户所做的任何更改。在没有任何类型的订户的情况下独自存在是完全满足的,并且不尝试吸引新订户。
KoratDragonDen 2014年

1
听起来您的设计不错。PS 在MVP之上考虑 MVC 的原因是,如果没有纪律,Presenter可能会负担过重。
拉里·奥布莱恩

1
+1是为了简单说明MVC和MVP之间的差异。像OP一样,互联网的其余部分让我完全迷失了这些首字母缩略词是否稍有不同。
Ixrec 2015年

5

我怀疑使您感到困惑的一件事是,有两种完全不同的模式,通常都称为模型视图控制器。

有一个在smalltalk中实现的原始文件,它对本地gui系统有用,还有我倾向于认为的web-mvc,它交换了一些视图和控制器的职责,以便控制器可以坐在服务器上。客户端上的视图(可能是呈现的html,或者可能是通过ajax)。

您的描述对我来说听起来像是大多数web-mvc定义中的描述。


这可以解释为什么我在围绕这个概念缠绕头时会遇到很多麻烦。谢谢; 很高兴知道我(可能)没有对MVC的概念做任何可怕的错误。
KoratDragonDen 2014年

对于现代的单页Web应用程序,我们回到客户端的经典MVC模式。
凯文·克莱恩

2

编程社区中有很多关于此确切术语的讨论。似乎没有人同意很多事情。

对我而言,桥如何连接到视图主要决定了名称。

  • 如果每个网桥可以有一个视图集合,则该网桥是一个控制器。
  • 如果每个网桥始终只有一个视图,则该网桥是演示者。
  • 如果每个视图可以有一组桥,那么该桥就是一个视图模型。

有时候事情不是那么清晰。例如,演示者可以连接到由多个子视图组成的复合视图,或者可以在不了解其视图的情况下创建控制器。尽管如此,我认为我的规则是一个好的开始。


附带说明一下,我喜欢将责任划分如下:

模型

主要职责:持久保存数据
次要角色:验证更新,将更新通知观察者

视图

主要职责:当前数据
次要角色:接受输入,当前用户体验

主要职责:更新数据
次要角色:清理输入,同步数据和视图


0

尽管您建议的模式从表面上看是正确的,并且无疑将适用于小型实例,但是随着您的应用程序变得越来越复杂,您将面临以下问题:不确定什么更新,谁在哪里听以及我为什么尝试?从如此多的视图中控制如此之多的模型,所有需要彼此访问的人,等等。

我建议您使用以下模式来扩展您的想法(摘自Amy Palamountain的《国家敌人》):

楷模

  • 与数据存储同步状态
  • 处理新/更新数据的验证
  • 改变状态时引发事件

观看次数

  • 渲染模板
  • 处理模型事件
  • 处理DOM事件
  • 中介模型与DOM之间的交互

控制器

  • 最多管理几个模型和视图
  • 跟踪容器内的视图

模组

  • 控制器及其视图和模型的逻辑分组
  • 可测
  • 小型且可维护(单一职责)
  • 协调(通过控制器)它包含的视图和模型的状态和事件
  • 免费发表自己的观点
  • 不能随意选择在哪里展示其观点

布局经理

  • 负责布局组成
  • 在DOM中定义应用程序外壳,其中模块可以显示其内容的区域

调度员

  • 收听事件(通过全球PubSub流)
  • 负责基于事件加载新模块
  • 将已加载的模块移交给布局管理器
  • 管理整个模块的整个生命周期(创建,清理,缓存等)
  • 事件示例:
    • 路线变更(包括初始装载路线)
    • 用户互动
    • 由于服务器端状态更改等,模块事件从Model事件冒泡

应用

  • 负责整体设置,实例化以下内容:
    • 调度员
    • 路由器
    • PubSub流
    • 记录仪
    • 等等

这种模式允许您的应用程序是可组合的,经过单元测试的,消除了Bridge随时间推移而建立的复杂性,使关注点保持良好分离等。

正如Amy所指出的那样:注意不要在客户端上构建服务器。注意不要落入“我正在制作MV *框架,因此我必须___!”的教义。相反,请考虑所有这些想法(以及此处的其他答案),并找到最适合您的应用程序和团队的方法。

我强烈建议您观看艾米·帕拉蒙特(Amy Palamountain)的演讲《国家敌人》(这些想法来自于此),或者至少浏览一下演讲的幻灯片

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.