21

我正在尝试学习 MVC 模式,但每个地方都有不同的说法。所以现在我不知道真正的 MVC 是什么。

所以我猜它是最纯粹的MVC:

  • 模型只是数据并通知数据更改。
  • View读取Model的消息以更新视图。
  • 控制器从视图中读取用户输入并据此更改模型。

实施

  • 模型不认识任何人。
  • View知道Model
  • Controller知道ViewModel

伪代码:

/* Model */
class Color{ 
  color = blue;
  setColor(color);
  notifyUpdate();
}
/* View */
class ColorPicker(model){
  model.register(update);
  update(){
    this.colorToExhibit = model.color;
  }
}
/* Controller */
class Colorize(view, model){
  view.register(update);
  update(color){
    model.setColor(color);
  }
}

一些问题:

  1. 那正确吗?
  2. 我不明白为什么视图不能直接更改模型,而是通过控制器。
  3. 假设我有一个动作后要执行的动画。谁必须处理这个动画:模型、视图还是控制器?另外:动画逻辑是模型、视图还是控制器的一部分?更多:假设一个扑克游戏。在用户选择一个动作(例如,“Raise”)后,系统必须播放动画(例如,筹码从玩家位置到桌子)。如何将这个扑克示例(带有动画)视为 MVC?你能解释一下并给出一个伪代码吗?

谢谢你。

4

3 回答 3

26
  • 模型只是数据并通知数据更改。
  • View 读取 Model 的消息以更新视图。
  • 控制器从视图中读取用户输入并据此更改模型。

模型不仅仅是数据。模型也是业务逻辑。它包含系统的所有智能,或者至少是幕后智能的抽象(例如数据库调用或其他服务调用)。想想这句话,“让你的模型重而你的控制器轻。”

  • 模型不认识任何人。
  • 视图知道模型。
  • 控制器知道视图和模型。

模型没有人知道它是正确的。模型应该在应用程序之间是可移植的,并且不应该以任何方式依赖于 UI 问题。(在这种情况下,视图和控制器是 UI 问题。)

视图知道模型,也是正确的。视图基本上“绑定”到模型。它呈现所有 UI 元素,并将模型数据相应地放置在 UI 元素中。

控制器类型“了解视图”。它知道它应该直接控制哪个视图,但它对那个视图一无所知。它也不知道先前来自哪个控件的哪个视图。控制器响应事件。来自 UI 的事件,带有某种状态信息(可能是 ViewModel),通过模型(业务逻辑发生的地方)引导逻辑控制,并以模型(或 ViewModel,如果形状特定于特定视图的数据不同于模型)和视图。

我不明白为什么视图不能直接更改模型,而是通过控制器。

View 可以在用户交互的上下文中操作 Model,但不应期望这些更改以任何方式持续存在。视图应该被认为是“客户端”并且不知道任何“服务器端”。(即使您谈论的是本机应用程序而不是 Web 应用程序。)持久化任何更改都被视为 UI“动作”或“事件”,并将转到控制器以使其发生。

假设我有一个动作后要执行的动画。谁必须处理这个动画:模型、视图还是控制器?另外:动画逻辑是模型、视图还是控制器的一部分?

动画听起来像是完全基于 UI 的操作。它将在视图内。除了 UI 动画,还有更多的事情发生吗?动画在后端有什么改变吗?例如,如果我有一个 Web 应用程序,并且当页面加载时,我想淡入一些数据(动画)......这完全在视图中。数据将像任何其他数据一样传递到视图,并且动画完全在 UI(视图)内进行。从模型或控制器的角度来看,它没有做任何事情。

假设一个扑克游戏。在用户选择一个动作(例如,“Raise”)后,系统必须播放动画(例如,筹码从玩家位置到桌子)。如何将这个扑克示例(带有动画)视为 MVC?你能解释一下并给出一个伪代码吗?

动作(“Raise”)是一个控制器事件。UI 将联系控制器以执行“提升”。所以控制器可能有这样的方法:

View Raise(GameState state)
{
    // Interact with the Models to update the known state of the game.
    // The Models would perform the actual Poker game logic.
    // Respond with a View bound to updated Models.
}

一旦控制器使用新视图响应 UI,该视图将包含要显示给用户的任何动画。(毕竟,除非动作成功,否则您不想执行动画,对吧?当 Controller 以指示成功动作的新 View 响应 UI 时,动画就会播放。它可能会改为响应 UI带有指示错误的视图,在这种情况下,该视图将显示其他内容。)

于 2012-05-27T13:41:34.997 回答
18

我将使用简单的银行类比。

  • 出纳员是意见。
  • 跑步者是控制器。
  • 银行家是模特。

银行家是聪明人,他们了解所有的业务逻辑并进行所有复杂的计算。

Runners 用于将钱(数据)从 Bankers 传输到 Tellers。

出纳员将钱交给客户。

一个简单的表示:

模型

public class BankAccount
{
     public int ID;
     public int Balance;

     public BankAccount(int id)
     {
         ID = id;
         Balance = DetermineAmount();
     }

     public int DetermineAmount()
     {
         // Gather transaction info, debits, credits and return a
         // sum of the amount left in the account depending on the
         // id provided.
     }
}

控制器

    public class BankAccountController
    {

         public ViewResult Index(int id)
         {
             BankAccount account = new BankAccount(id);
             return View(account);
         }

    }

看法

<ul id="account-info">
   <li>Account ID: `@Model.ID`</li>    
   <li>Balance: `@Model.Balance`</li>
</ul>
于 2012-05-27T14:57:39.300 回答
9

如果您对历史上真正的MVC 感兴趣,请从Trygve Reenskaug开始。他在 1970 年代后期创建(观察到?,编目??)它。首先,请阅读1979 年的“模型-视图-控制器” 。它定义了术语。请注意它的标题——所有三个角色都是多元化的。这是大多数人似乎弄错的第一件事。

我发现的关于 MVC 最初使用的最佳描述实际上是在 2004 年题为“Inside Smalltalk MVC”的演示文稿中。我猜想描述 Smalltalk 80 最终版 MVC 的规范论文是 Krasner 和 Pope 的“A Cookbook for Using the Model-View-Controller User Interface Paradigm in the Smalltalk-80”和 Steve Burbeck 的“Applications Programming in Smalltalk-80” :如何使用模型-视图-控制器(MVC)”。这两篇论文都非常值得一读。

如果您有时间消磨时间并且不介意聆听 Robert Martin,他在 Ruby Midwest 2011 上做了一个很好的主题演讲,涉及 MVC。这是一个多小时,但非常有趣和有启发性。我倾向于遵循他的观点,即大多数实现都会导致 MVC 错误。我花了一点时间环顾四周,最后找到了一个可以链接到描述 MVC 的图表。我喜欢的那个来自Pope 和 Krasner

MVC
(来源:as3dp.com

在我看来,以下是关键点:

  • 模型实例负责通知感兴趣的对象发生变化。请注意,这些可以是任何对象实例。该图显示了在此处接收更新的视图和控制器。
  • 视图负责查询当前状态并显示结果。他们通常也执行过滤或数据转换。
  • 控制器负责接受用户输入并将视图消息转发到视图。
    • 查看消息是 MVC 中的一个常见主题。重要的是这些独立于 UI 世界 - 这些不是鼠标单击,而是特定于视图的事件语言。这将我们带到了下一点。
  • 视图不以任何方式依赖于控制器。控制器负责安排和创建视图,并提供世界其他部分和视图之间的接口。
  • 在一个完美的世界中,视图负责使模型表示可见。这就是将 MVC 应用于桌面应用程序时的工作方式。

现实情况是,MVC 已经为 web 世界被扭曲和重写。它不再是真正的 MVC,或者可能只是重新定义了 MVC。这就是为什么你会看到这么多不同的 MVC 观点和表示。如果你正在研究编写桌面风格的应用程序,那么看看 Krasner & Pope 的东西。如果您正在研究如何将 MVC 应用于 Web,那么我推荐 Bob 叔叔的主题演讲,以寻找更适合 Web 应用程序的替代方案——他称之为交互器、实体、边界架构,因为没有更好的名称。挖掘与他关于“建筑失落的岁月”的谈话相关的内容。

于 2012-05-27T14:39:57.307 回答