MVC:我需要了解模型

Posted

技术标签:

【中文标题】MVC:我需要了解模型【英文标题】:MVC: I need to understand the Model 【发布时间】:2011-09-09 19:50:54 【问题描述】:

我使用 MVC 模式已经有一段时间了,但老实说,我并不真正了解如何使用和应用“模型”......我的意思是,一个人可以轻松逃脱只使用控制器和视图就可以了。

我了解模型的概念,但我不习惯在模式中应用它...我在 .NET 中使用 MVC 模式,也使用 Wheels for ColdFusion。

“模型代表应用程序的信息(数据)和用于操作数据的业务规则” - 是的,我明白了......但我只是不明白如何应用它。将调用路由到控制器并让控制器调用数据库、组织数据然后将其提供给视图会更容易。我希望有人能理解我的困惑所在......

提前感谢您的帮助!

【问题讨论】:

您能否进一步解释您如何“组织数据并使其可用于视图”。根据您如何执行此操作,您可能已经有了模型的常规实现(如 Sergi 所述),或者更容易提出改进建议(如 Ben 的回答)。 假设调用了: /user/login ... 路由被调用并且用户控制器有一个名为 "login" 的操作。此时,我可以在登录操作中执行所有逻辑(检查数据库中的用户并对其进行身份验证),然后在视图中显示结果。如果我理解每个人在说什么,我应该有一个“用户”模型,其中包含处理各种任务的功能,例如“userLogin”、“userUpdate”以及“用户”可能想要在站点范围内执行的任何其他任务? 我认为您的问题更多是关于面向对象编程而不是 MVC。您需要先掌握面向对象的编程,然后再考虑 MVC 的用途。 不,根本不是这样。我了解如何使用对象。我需要了解如何组织 MVC 模式。 你的User模型不应该有任何功能;理想情况下,模型类将只有属性。您应该将模型类视为数据容器、信息传输器。除此之外,它们(主要)是“愚蠢”的对象。让您的 LoginController(或 LoginService 或其他)处理业务逻辑,然后用有关登录用户的数据填充 User 对象并将其传递给视图以进行显示。达达!你得到了一个模型类:User 【参考方案1】:

这是我之前解释过的方式:

控制器:确定执行、包含哪些文件等,并将用户输入(如果存在)传递给这些文件。

视图:用于向用户显示输出的任何内容。

型号:其他一切。

希望对您有所帮助。

【讨论】:

【参考方案2】:

该模型包含业务逻辑(即重要的算法)和持久性交互 - 通常与数据库。控制器是 MVC 框架:Wheels、Struts、.NET 的 MVC 方法。视图显示控制器从模型中检索的数据。

MVC 的主要理念是视图和模型应该不知道控制器 - 即没有耦合。在实践中,至少存在一些耦合,但如果做得好应该是最小的,这样就可以轻松地更改控制器。

所以应该发生的是请求到达控制器,通常是front controller,其中应该有一些您编写的粘合代码,它们要么扩展某些控制器对象,要么遵循一些命名约定。此胶水代码负责调用正确的service layer 对象上的方法,将该数据打包到某种帮助器(通常是Event 对象)中,并将其发送到正确的视图。然后视图从 Event 对象中解包数据并相应地显示。

如果做得好,这会产生一个可单元测试的domain model(又名模型)。这样做的原因是您已经将算法与任何框架或视图依赖项分开。这样您就可以独立验证这些。

【讨论】:

【参考方案3】:

这样看。当您的客户请求页面时,会发生这种情况(大量修剪):

他最终在你的控制器

控制器从您的模型

获取必要的数据

然后控制器将数据传递给 view,这将创建您的 html

控制器将 HTML 发送回客户端

所以客户端->控制器->模型->控制器->视图->控制器->客户端

那么模型是什么?这是获取您查看所需的数据所需的一切!

是服务

是数据访问

是查询

是对象映射

“抛出异常”样式验证很关键

如果您坚持这种模式,您的控制器应该编写您的查询。您的控制器应该获得正确的 data 以呈现正确的 view

您的控制器可以做一些其他事情,例如验证发布的数据或一些 if/else 逻辑,但不查询数据 - 只需调用服务(在您的模型区域中)来获取您的视图所需的数据。

【讨论】:

这就是我开始理解模型的方式......但随后@Sergi Papaseit 提到,除了对象的占位符属性之外,不应该有任何东西。我开始认为,真的没有明确的认识…… @dcolumbus - 该模型非常庞大,但......它本身有很多层。并不是没有清晰的认识。没有一种“正确”的方法可以做到这一点。 @BritishDeveloper 的概述是准确的。控制器“组织”应用程序。视图显示。模型处理数据。它如何处理它是主观的。简而言之,这就是模型所做的。 你是说查询应该在模型中? 是的,查询绝对应该在模型中。也许在模型中的服务对象中。也许在模型中的 DAO 对象中。再次......这取决于模型的架构方式。但是查询...肯定在模型的某个地方。 您提到将查询放在控制器中似乎更简单。但是如果你在多个控制器文件中有多个方法需要做同样的事情呢?你要复制那个代码吗?或者您打算从控制器的不同位置调用模型中的单个方法?这可能有助于说明为什么应该将查询推出控制器。【参考方案4】:

我想这正是您决定在应用程序中调用不同位的原因。无论您使用哪个类将信息从控制器传递到视图,都可以被视为/称为“模型”。

通常我们称Model为我们的实体类,我们称View Model为“助手”类,由于没有更好的词,我们使用“纯”实体(即,将存储在database) 不足以在 View 中显示我们需要的所有信息,但这主要是一个命名的东西。

你的模型类不应该有任何功能; 理想情况下模型类将只有属性。您应该将模型类视为数据容器、信息传输器。除此之外,它们(主要)是“愚蠢”的对象:

// This would be a model class representing a User
public class User

    public int ID  get; set; 
    public string Name  get; set; 
    public string Email  get; set; 

您如何将信息(无论在您的上下文中可能意味着什么)从控制器传递到视图,反之亦然?那么,这就是你的模型。 :)

【讨论】:

我在上面的问题中添加了更多内容^^ 我仍在扩展我的答案:þ 我们的控制器和视图在这一点上如何相互交互? 我在上面评论了我的帖子^^ 我不确定你会得到比这个更清楚的解释。 为什么你的模型类中不应该有函数?这是我采用的方法,我发现将我的对象的功能从简单的哑对象扩展开来真的很有帮助。【参考方案5】:
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>

这个想法是分离关注点。为什么不在视图中也有控制器逻辑?模型代表业务对象,控制器操纵这些对象以执行某种任务,视图呈现结果。这样,您可以将整个视图换成不同的视图,而不必重写整个应用程序。您还可以让人们在不同的层(模型、控制器、视图)上工作,而不会在很大程度上影响其他层。

通过结合控制器和模型,您的代码的可维护性和可扩展性会降低。您基本上没有执行面向对象的编程,因为您没有将数据库中的事物表示为对象,您只是将数据取出并将其发送到视图。

【讨论】:

【参考方案6】:

模型是基础对象的代码表示。虽然一些数据密集度较低的系统在 MVC 的模型端可能很轻,但我相信您总能找到适用的用途。

让我们举一个人为的(但现实的)例子来说明模型的有用性:

假设我正在创建一个博客。我的博客有 Post 对象。现在,帖子在网站内外使用,并由系统中的许多用户添加。我们的系统是为人们在他们的帖子中输入 HTML 进行编码的,但是低调看,人们开始添加粘贴的文本。此文本使用“\n”作为换行符。

对于模型,这是一个相对简单的修复。我们只需创建一个覆盖 postText 的 getter:

public function get postText() 
    return this.postText.replace("\n", "<br />");

突然之间,我们可以通过几行简单的代码影响整个网站的行为。如果没有模型的实现,我们需要在使用 postText 的地方找到并添加类似的功能。

随着时间的推移,MVC 中的模型完全是关于代码库的封装和灵活性。您使用它并以这种方式思考的次数越多,您就越会发现其他情况,否则这将是一场噩梦。

--编辑(您已添加到上面的问题中):

让我们以同样的例子并使用您的控制器调用数据库。对于使用 Post 对象的各种页面/系统,我们有 9 个控制器类。决定我们的 Post 表现在需要有一个delete_fl。我们不再希望使用delete_fl = 1 加载帖子。

在我们的 Post 模型正确实施后,我们只需编辑 loadPosts() 方法,而不是在整个网站上搜索所有案例。

一个重要的认识是,在任何主要系统中,模型更多的是文件集合,而不是单个单体。通常,每个数据库表都有一个模型文件。用户、帖子等

【讨论】:

好的,这对这一切有了更深入的了解......仍然不完全清楚。

以上是关于MVC:我需要了解模型的主要内容,如果未能解决你的问题,请参考以下文章

MVC - 我需要在视图中使用控制器吗?

MVC 4 - 在哪里保留业务逻辑

在 MVC 应用程序中从模型正确调用数据库?

Javaweb的MVC模式和三层架构(框架了解)

在单独的程序集中使用 MVC 2.0 和模型

MVC 2 视图布局 CSS 控件布局