MVC 混乱;梳理模型职责和结构

Posted

技术标签:

【中文标题】MVC 混乱;梳理模型职责和结构【英文标题】:MVC Mayhem; Sorting out Model responsibility and structure 【发布时间】:2011-07-18 20:07:35 【问题描述】:

在过去的几周/几个月里,我对 MVC 类型架构的理解有了很大的进步(我想说),我要感谢 SO 爱好者们;所以,谢谢!

尽管如此,我仍然受到Model 的挑战。至此我已经整理并创建了;

一个简单的Request 对象,用于整合请求数据(GET/POST/等参数、HTTP 标头等) 一个简单的Response 对象,用于收集响应数据(html、JSON、HTTP 标头等) 一个奇特的Router,它根据正则表达式驱动的路由表解析URI,根据Controller文件/类的存在/继承来验证它们,并使用任何补充参数更新Request对象。 一个简单的Dispatcher 对象,用于设置工作环境、创建和初始化必要的Controller,并向其发送RequestResponse 对象以供使用。

现在是Model

我了解,在许多(某些)情况下,Model 仅代表它的关联实体、表格,以及 CRUD 方法(addUser()deleteUser() 等)。其他还有更深层次的抽象,防止控制器访问更细粒度的 CRUD 功能,合并方法(replaceUser() - 删除、添加,然后返回用户数据

我想知道我最好的做法是什么;出于一些具体原因。

我创建了一个Gateway 类,它充当预期Model 的代理,执行ACL 检查(使用Acl 对象,特例“Model ) 使用Request 和所需的方法和参数作为检查的参数。 Controller 负责确定 ACL 检查失败的结果(显示除该数据之外的所有数据、重定向等)

我还引入了一个(之前我将其称为混合 REST/RPC,但我认为这是不正确的,因为我的资源 URI 架构是窗外)RPC API层。 API 调用由方法、参数和请求参数组成,由特殊的ApiController 管理,并像普通的Model 调用一样被馈送到Gateway

在我看来,促进数据访问的最佳方式是(uh-oh)单个巨大的模型对象,不考虑任何 ORM,维护所有数据库交互方法,证明简单管理网关/ACL/模型关系。 不,这听起来不对。

鉴于这些架构选择,我的最佳选择可能是对我的,嗯..Model 建模?上述的设计选择是否真的把谨慎和最佳实践抛在了脑后?

【问题讨论】:

模型应该只作为你的数据提供者的代理,并且应该只被控制器或视图访问,如果其中任何一个是错误的,那么你应该重组你的代码,使它适合这个安排。 @RobertPitt; 这基本上就是我正在做的事情(打算)。 PageControllerGateway 说“给我用户列表”。 Gateway 基于身份验证说“Yay”或“Nay”。如果是“Yay”,它将方法调用转发到提议的Model,并且所述方法验证并返回一个数据集,Controller 最终发送到View 进行渲染。 API 调用是一样的,除了 ApiController 而不是 PageController 并且每个方法调用都是单独请求并通过 Gateway 发送的,以 JSON 形式返回而不是 View 我想的问题是我的页面控制器不以任何方式表示实体。在我的方法中,User_Model 旁边没有User_Controller。页面控制器比这更抽象,代表视图的意图,而不是关联的模型。 有个东西叫View Model,可以和Domain Model不同 值得阅读,可能与您的部分问题有关:"... MVC as it was originally conceived about twenty years ago doesn't actually work on the web." 【参考方案1】:

也许这只是语义,但我会说模型是封装应用程序中实体的数据、类(以及对象的扩展)的表示。还有另一个缺失的部分,我将其称为持久性或数据访问层 (DAL)。 MVC 作为一种抽象并不真正关心持久性,因为您实际上不必具有持久性来使用 MVC 模式进行开发。在(几乎?)所有使用 MVC 的 Web 应用程序中,您确实有一个数据库,因此确实需要一个持久层。持久层理解模型并将其提供给控制器,但它实际上并不是模型的一部分。

如果您将插入/检索/更新数据的概念分离到持久层中,那么您剩下的就是封装应用程序实体表示的容器和相关的业务/验证逻辑。这些应该相对较小,重点突出,并且仅相互依赖于实体之间的实际数据依赖关系。这个小模型,每个实体一个,总共包含您的应用程序的模型。您的持久层 (DAL/ORM) 也不是特别大,而是仅专注于与数据库交互以获取/存储模型。

【讨论】:

感谢 tvanfosson; 为了澄清我的理解,在这种情况下,持久层是指控制器和模型之间的一层,它将模型功能聚合到一个(缺少更好的术语)可查询实体,代表应用程序状态(模型本身) 在另一种意义上,我的应用程序层可以描述为; View-ViewController-ModelController-Model,View 和 Model 都接受了一层抽象胶水。 @Tomcat - 我不确定我是否理解您的描述,但我会说控制器使用持久层来存储/检索域模型,是的。我为 Web 描述 MVC 的方式是控制器响应和解释 HTTP 请求。他们从持久性介质中获取相关的领域模型,通常将它们转换为特定于视图的模型,这些模型可能包含比领域模型更多或更少的数据。他们选择要渲染的视图并将视图模型交给它。视图将数据呈现为 HTML 响应,该响应被发送回客户端。 ...我会注意到,为了简单起见,我省略了一些基础架构的 guts:路由引擎、渲染引擎、模型绑定器等。 @tvanfosson; 自从我发表评论后阅读了一些内容,我意识到我的解释和理解存在错误。我想我在尝试将这一切联系在一起时遇到的 主要 问题是我的应用程序架构没有明确使用在许多 MVC 框架中至关重要的 CoC(Convention-over-Configuration)和架构。 server.com/user/addUser 数据之间没有关系。控制器“代表视图的意图”,而不是模型。不过,CoC 存在于我的应用程序中,作为使用 php 魔术来获取控制器名称的一种方式。 @tomcat - 您正在寻找的抽象是存储库模式,css.dzone.com/books/practical-php-patterns/…(这里是 php)和martinfowler.com/eaaCatalog/repository.html(原始)。

以上是关于MVC 混乱;梳理模型职责和结构的主要内容,如果未能解决你的问题,请参考以下文章

互联网数据分析师职责要求

sap实施顾问基本职责

MVC架构的职责划分原则

用分层结构打造苗条 MVC 框架 |译文

职责的界定方法

一个JDBC访问oracle数据库表的例子,让你搞清三层架构与MVC框架模式之间的关系,以及满足设计原则的类的结构和各类的职责