当前位置:  开发笔记 > 编程语言 > 正文

MVC中的模型究竟是什么?

如何解决《MVC中的模型究竟是什么?》经验,为你挑选了3个好方法。

关于模型究竟是什么,我有点困惑.我知道它适用于来自数据库等的数据.它可以用于其他任何东西吗?例如,一个身份验证系统,在用户注册时向用户发送激活电子邮件.哪个是最适合放置电子邮件代码的地方?模型是否合适......或者更好地放在视图,控制器等中?



1> Breton..:

想想这样.您正在设计应用程序,并且根据路线图您知道版本1除了基于文本的命令行界面之外什么也没有.版本2将具有基于Web的界面,版本3将使用某种gui api,例如windows api或cocoa,或某种跨平台工具包.没关系.

该程序可能也必须跨越不同的平台,因此他们将需要使用不同的电子邮件子系统.

该模型是程序中不会在这些不同版本中发生变化的部分.它构成了逻辑核心,可以完成程序所做的任何特殊事情的实际工作.

您可以将控制器视为消息转换器.它有两面接口,一面朝向模型,一面朝向视图.当您创建不同的版本时,主要活动将重写视图,并更改控制器的一侧以与视图交互.

您也可以将其他平台/版本特定的东西放入控制器中.

在本质上,控制器的工作是帮助您将模型中的域逻辑与转储到视图中的任何特定于平台的垃圾或其他模块分离.

因此,为了弄清楚模型中是否存在某些内容,请问自己"如果我必须重写此应用程序以在平台X上工作,那么我是否必须重写该部分?" 如果答案是肯定的,请将其保留在模型之外.如果答案是否定的,那么它可能会进入模型,如果它是程序基本逻辑的一部分.

这个答案可能不是正统的,但这是我发现MVC范式的唯一方式,这种范式并没有让我的大脑从毫无意义的理论愚蠢的大脑中消失,因为关于MVC的讨论如此充满.


+1因为这是我遇到的唯一一个没有让我思考的解释,"哎呀,模特似乎同时是武断的,语无伦次的,可能是不必要的" - 事实上,让我认为恰恰相反.谢谢.

2> hobodave..:

好问题.在我早期的MVC时代,我多次问过同样的问题.这是一个难以回答的问题,但我会尽我所能.

该模型通常代表您的应用程序的"数据".但是,这并不限制您访问数据库.您的数据可以是XML文件,Web资源或许多其他内容.该模型封装并提供对此数据的访问.在OOP语言中,这通常表示为对象或对象集合.

在这个答案中我将使用以下简单示例,我将这种类型的对象称为实体:



在最简单的应用程序中,例如电话簿应用程序,此实体将代表电话簿中的人员.您的视图/控制器(VC)代码将使用此实体以及这些实体的集合来表示电话簿中的条目.您可能想知道,"好的.那么,我该如何创建/填充这些实体?".一个常见的MVC新手错误就是直接在其控制器方法中直接开始编写数据访问逻辑,以创建,读取,更新和删除(CRUD)这些.这不是一个好主意.这些实体的CRUD职责应该存在于您的模型中.我必须强调:模型不仅仅是数据的表示.所有CRUD职责都是模型层的一部分.

数据访问逻辑

用于处理CRUD的两个更简单的模式是表数据网关和行数据网关.一种常见的做法,通常是"不是一个好主意",只是让您的实体对象直接扩展您的TDG或RDG.在简单的情况下,这样可以正常工作,但它会使您的实体充满不必要的代码,这些代码与应用程序的业务逻辑无关.

另一种模式Active Record通过设计将所有这些数据访问逻辑放入实体中.这非常方便,并且可以极大地促进快速发展.这种模式在Ruby on Rails中广泛使用.

我个人选择的模式,也是最复杂的模式是Data Mapper.这提供了数据访问逻辑和实体的严格分离.这使得精益业务逻辑专有实体成为可能.数据映射器实现通常使用TDG,RDG甚至Active Record模式为映射器对象提供数据访问逻辑.实现数据映射器使用的标识映射是一个非常好的主意,可以减少对存储介质执行的查询数量.

领域模型

该领域模型是您的域的对象模型,结合行为和数据.在我们简单的电话簿应用程序中,这将是一个非常无聊的单人类.我们可能需要向域添加更多对象,例如雇主或地址实体.这些将成为域模型的一部分.

域模型非常适合与Data Mapper模式配对.您的控制器只需使用Mapper来CRUD视图所需的实体.这使您的控制器,视图和实体完全不受存储介质的影响.这也允许同一实体的不同Mapper.例如,您可以拥有Person_Db_Mapper对象和Person_Xml_Mapper对象; Person_Db_Mapper将使用您的本地数据库作为构建实体的数据源,Person_Xml_Mapper可以使用某人上传的XML文件,或者您使用远程SOAP/XML-RPC调用获取的XML文件.

服务层

的服务层图案定义了与服务的层,其建立了一套可用的操作,并协调在每个操作中的应用程序的响应的应用程序的边界.我认为它是我的域模型的API.

使用服务层模式时,您将数据访问模式(Active Record,TDG,RDG,Data Mapper)和域模型封装到方便的单一访问点中.此服务层由控制器直接使用,如果实现良好,则可以方便地挂钩其他API接口,例如XML-RPC/SOAP.

服务层也是放置应用程序逻辑的适当位置.如果您想知道应用程序和业务逻辑之间的区别是什么,我将解释.

业务逻辑是您的域逻辑,您的域模型所需的逻辑和行为,以适当地表示域.以下是一些业务逻辑示例:

每个人都必须有一个地址

没有人可以拥有超过10位的电话号码

删除人员时,应删除他们的地址

应用程序逻辑是不适合您的域的逻辑.这通常是您的应用程序需要的东西,放入业务逻辑是没有意义的.一些例子:

删除Person时,请向系统管理员发送电子邮件

每页最多只显示5个人

添加逻辑以向我们的域模型发送电子邮件是没有意义的.我们最终将我们的域模型与我们正在使用的任何邮件类联系起来.我们也不想限制我们的Data Mapper一次只获取5条记录.在服务层中具有此逻辑允许我们可能不同的API具有其自己的逻辑.例如,Web可能只获取5,但XML-RPC可能会获取100.

最后,并不总是需要Service ayer,并且对于简单的情况可能会过度杀伤.应用程序逻辑通常直接放在您的Controller中,或者不太理想,放在您的域模型(ew)中.

资源

每个认真的开发者都应该在他的图书馆里有这些书

设计模式:可重用面向对象软件的元素

企业应用架构模式

领域驱动设计:解决软件核心的复杂性



3> Extrakun..:

该模型是您表示应用程序数据的方式.它是应用程序的状态,是影响应用程序输出(编辑:可视化表示)的数据,以及可由控制器调整的变量.

要具体回答你的问题

电子邮件的内容,发送电子邮件的人是模型.

发送电子邮件(并首先验证电子邮件/注册)并确定电子邮件内容的代码位于控制器中.控制器还可以生成电子邮件的内容 - 也许您在模型中有一个电子邮件模板,控制器可以用其处理中的正确值替换占位符.

视图基本上是"身份验证电子邮件已发送到您的帐户"或"您的电子邮件地址无效".因此,控制器查看模型并确定视图的输出.

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有