MVC系统如何工作?

时间:2012-05-27 13:16:14

标签: model-view-controller oop design-patterns

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

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

  • 模型 只是数据并通知数据更改。
  • 查看会读取模型的消息以更新视图。
  • 控制器查看读取用户输入并根据更改模型。

实施

  • 模特不认识任何人。
  • 查看了解模型
  • 控制器知道查看模型

伪代码:

/* 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. 我看不出为什么查看无法直接更改模型,而是通过Controller。
  3. 假设我有动作后要执行的动画。谁必须处理这个动画:模型,视图或控制器?另外:动画逻辑是模型,视图或控制器的一部分?更多:假设一个扑克游戏。在用户选择动作(例如,'提升')之后,系统必须播放动画(例如,从玩家地点到桌面的筹码)。我如何看待这个扑克示例(带动画)作为MVC?你能解释并给出一个伪代码吗?
  4. 谢谢。

3 个答案:

答案 0 :(得分:25)

  
      
  • 模型只是数据并通知数据更改。
  •   
  • View会读取模型的消息以更新视图。
  •   
  • Controller从View中读取用户输入并根据更改模型。
  •   

模型不仅仅是数据。该模型也是业务逻辑。它包含系统的所有智能,或者至少是幕后智能的抽象(例如数据库调用或其他服务调用)。考虑一下这样的说法,“让模型保持沉重,控制器亮起。”

  
      
  • 模特不认识任何人。
  •   
  • 查看了解模型。
  •   
  • Controller知道View和Model。
  •   

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

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

Controller 种类“知道视图。”它知道它应该直接控制哪个View,但它不知道关于那个View。它也不知道哪个视图来自哪个控件。 Controller响应事件。从UI进入事件,携带某种状态信息(可能是ViewModel),通过模型(业务逻辑发生的地方)引导逻辑控制,并使用模型(或ViewModel,如果形状)进行响应特定视图的特定数据与模型和视图不同。

  

我看不出为什么View无法直接更改模型,而是通过Controller。

View可以在用户交互的上下文中操作Model,但不应期望这些更改以任何方式持续存在。 View应被视为“客户端”,并且不知道“服务器端”。 (即使您谈论的是本机应用程序而不是Web应用程序。)保留任何更改都被视为UI“操作”或“事件”,并且会转到Controller以实现它。

  

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

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

  

假设一场扑克游戏。在用户选择动作(例如,'提升')之后,系统必须播放动画(例如,从玩家地点到桌面的筹码)。我如何看待这个扑克示例(带动画)作为MVC?你能解释并给出一个伪代码吗?

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

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.
}

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

答案 1 :(得分:18)

我会选择简单的银行类比。

  • Tellers是视图。
  • 跑步者是控制者。
  • 银行家是模特。

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

The Runners用于将资金(数据)从银行家转移到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>

答案 2 :(得分:8)

如果您对历史 true MVC感兴趣,请从Trygve Reenskaug开始。他在20世纪70年代后期创作(观察?,编目??)。首先,请阅读1979年的"Models-Views-Controllers"。它定义了术语。仔细注意它的标题 - 所有三个角色都是多元化的。这是大多数人似乎首先出错的第一件事。

我发现MVC最初使用的最佳描述实际上是在2004年的题为"Inside Smalltalk MVC"的演示文稿中。我猜想描述Smalltalk 80最终版MVC​​的规范论文是Krasner&amp;教皇的"A Cookbook for Using the Model-View-Controller User Interface Paradigm in the Smalltalk-80"和  史蒂夫伯伯克的"Applications Programming in Smalltalk-80: How to use Model-View-Controller (MVC)"。这两篇论文都值得一读。

如果你有时间杀人并且不介意听罗伯特·马丁,他做了一个很好的keynote at Ruby Midwest 2011触及了MVC。这是一个多小时,但非常有趣和启发。我倾向于认为大多数实现都会使MVC出错。我花了一点时间环顾四周,最后找到了一个我可以链接到哪个图表来描述MVC。我喜欢的那个来自 Pope和Krasner

MVC http://www.as3dp.com/wp-content/uploads/2010/02/mvc_pope_krasner.png

从我的观点来看,以下是关键点:

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

现实情况是,MVC已被扭曲并重写为网络世界。它不再是真正的MVC,也可能只是重新定义了MVC。这就是为什么你会看到很多不同的意见和MVC表示的原因。如果你正在研究编写桌面风格的应用程序,那么看看Krasner&amp; amp;教皇。如果你正在研究MVC如何应用于网络,那么我推荐Uncle Bob的主题演讲,它更适合于Web应用程序 - 他称之为 Interactor,Entity,Boundary Architecture 缺乏一个更好的名字。挖掘与他关于“失落的建筑年代”的谈话相关的东西。