【问题标题】:In ideal MVC should the view know the model?在理想的 MVC 中,视图应该知道模型吗?
【发布时间】:2011-04-14 02:38:20
【问题描述】:

我的问题是关于理想的或原始的 MVC 解释 http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html

由于 MVC 的目标是减少依赖,视图应该知道模型吗?那有什么办法可以防止它变胖,直接调用Model Methods而不问Controller呢?

更新:当我阅读下面的答案时,我将举一个具体的例子:

假设您创建了一个复杂的计算器(不仅仅是一些简单的计算器,比如说股票市场的期权定价器)。它只需要像股票价格、利率、波动率这样的输入。那么,既然我只需要这些输入变量,为什么还要创建对包含视图中方法的整个模型的引用呢?

为什么控制器不会在视图发生变化时得到通知,然后只用输入回调视图中的方法?

例如,在这里我看到 View 引用了整个模型:

http://leepoint.net/notes-java/GUI/structure/40mvc.html

private CalcModel m_model;

【问题讨论】:

    标签: model-view-controller design-patterns language-agnostic


    【解决方案1】:

    是的,在 MVC 中,视图知道模型。事实上,视图的工作是显示模型,所以它必须知道模型。模型应该相当简单,不应该是状态容器(即字符串、整数等属性)——它不应该有方法。

    控制器知道视图和模型——控制器的工作是获取适当的模型并将其传递给适当的视图。

    模型应该完全不知道控制器或视图。

    这是 MVC (SoC) 中典型的关注点分离,其中每个组件都有其明确定义的“工作”。

    【讨论】:

    • 显示模型并不意味着它需要知道整个模型,只需要知道要显示的数据。模型 OBJECT 不仅仅是数据:它还包含方法。
    • “它还包含方法”——这取决于你问谁是主观的。 :) 此外,通常我们使用“视图模型”,其中包含您要显示的数据。这可能与您的域模型 100% 匹配,也可能不匹配。
    • 那我参考MVC的原发明者heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html是不是还是主观的:)
    • 是的,它仍然是主观的。多年来,模式一直在适应,您会在整个技术范围内看到 MVC 的大量不同“风格”和实现。模式从来都不是万能的。
    【解决方案2】:

    在 MVC 中,重点不在于您不应该在 M-V-C 之间进行通信。关键是将模型与视图(和控制器)分开,以便您可以轻松更改/替换组件。

    http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller

    【讨论】:

      【解决方案3】:

      视图不应该知道 business 模型,这取决于控制器。然而,视图应该知道 data 模型。它还必须如何呈现?

      另见:

      【讨论】:

      • 那么具体是什么意思?您会在视图中创建对整个模型类的引用,还是仅对将由控制器传递给视图的数据结构的引用?
      • 视图不创建数据模型,视图只是访问/使用它。所以,是后者。
      • 控制器将模型提供给视图。视图不知道这些数据来自哪里,只是要渲染它。如果“模型”有方法等,那么它做的太多了。
      • @user:视图引用了模型来显示数据。视图尚未创建它。视图不会调用模型上的操作/业务方法。控制器这样做。视图只访问数据方法(通常是 getter 方法)来获取数据以供显示。此外,必须注意“模型”(业务或数据)中的歧义。链接的示例将业务和数据模型紧密耦合在一个类中。
      • 应该注意 MVC 组件的角色定义往往从 GUI 应用程序到 Web 应用程序不同
      【解决方案4】:

      那么什么会阻止它变成 fat 直接调用模型方法 不问控制器?不问控制器?

      我觉得这有点幽默。视图没有自己的思想,但程序员有。他们是那些做出错误决定并允许 View 做它所做的事情的人。

      View 必须对 Model 有足够的了解才能显示。如果您的程序员无法控制自己,一个答案可能是让他们的 Model 对象不可变。

      另一个可能是使用 AOP。编写一个切面来防止对服务层的调用不是来自其他服务或控制器。

      还有另一种观点:AJAX 就是 View 将事情掌握在自己手中,并在未经任何人许可的情况下调用服务,以异步执行操作并提高响应能力以获得更好的用户体验。这是一件的事情。

      不要过于拘泥于建筑的纯粹性。 MVC 是一种很好的模式,在应用时非常有用。了解规则;知道什么时候适合打破规则。不要那么教条——无论是编程还是生活。

      【讨论】:

      • 例如,如果您需要在将模型持久化到数据库之前修改模型,如何使模型对象不可变?
      • 正如我上面所说,为什么要通过整个模型?为什么不只显示愚蠢的数据?
      • @user310291 - 这是您最终获得并行可变和不可变对象层次结构的地方。业务对象和 DTO。我并不是说我喜欢这个设计,但是那些非常在意“层纯度”的人通常会选择它。这就是你传递“愚蠢数据”而不是整个模型的想法。
      • 如果视图通知控制器然后将其传递回哑数据,我不明白为什么您需要创建不可变的东西?
      • 那你不同意 BalusC 吗?
      【解决方案5】:

      视图的目标是呈现从模型派生的数据。所以答案是不应该。另一方面,模型不应该关心这些数据将如何呈现。

      例如,业务逻辑可能是:

      查看->报告->年收入= 这->first_quarter_rev + 这->second_quarter_rev + 这->third_quarter_rev + 这->fourth_quarter_rev;

      同时呈现逻辑:

      if (!this->report->annual_revenue) { print('没有信息') } 别的 { print(format('# ###', this->report->annual_revenue) + '$'); }

      【讨论】:

        猜你喜欢
        • 2015-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-26
        • 2013-03-25
        • 2011-04-18
        • 1970-01-01
        相关资源
        最近更新 更多