【问题标题】:MVC: Where should I put this data access logic?MVC:我应该把这个数据访问逻辑放在哪里?
【发布时间】:2012-08-21 18:34:51
【问题描述】:

我一直在尝试在家里重建个人 Web 应用程序时遵守对 MVC 的严格解释,但我遇到了一些问题。

该应用程序是一个财务跟踪应用程序。我被困在第一页,这只是本月银行账户交易的列表。交易清单是我的模型。在这一点上,Controller 和 View 很容易想象。

但是,我在页面顶部还有两个按钮。它们是箭头,一个对应上个月,另一个对应下个月的交易清单。如果上个月/下个月没有交易,我不希望启用这些按钮,因此我需要与数据库交谈以确定每个按钮是否应该实际链接到某个地方。

从我读过的大部分内容来看,数据库访问应尽可能封装在模型中,在控制器和视图中几乎没有数据库访问。

但是,这些按钮本质上需要询问数据库,“下个月/上个月是否有任何交易?”答案将决定他们的链接是否被禁用,以及将用户发送到哪里。

严格来说,将它们的逻辑放入事务列表模型似乎并不合适,因为事务是否存在请求范围之外超出了事务列表模型的关注范围。

我想我还可以制作另一个模型,该模型将对应于所有存在交易的年月组合。然后我可以将此模型和事务列表传递给正确的视图。

或者我应该偏离模型外的无数据库访问范式,而只是将一些快速的数据库查询扔到视图中(因为结果本质上是一个 UI 问题,从而使导航更容易)?

你们如何看待这个概念性问题?

顺便说一句,我没有使用任何框架。这是一个宠物项目,旨在让我更熟悉 MVC 模式的具体细节。

【问题讨论】:

    标签: model-view-controller


    【解决方案1】:

    ...我是否应该偏离 no-database-access-outside-the-model 范式,而只是将一些快速的数据库查询扔到视图中...

    简短的回答是:。如果你真的对学习 MVC 和更好的编码感兴趣,那么走捷径“仅仅因为” 是一个非常糟糕的主意。领域逻辑分离是 MVC 的一个基本概念,违反它本质上就是从 MVC 转移到由糟糕的代码和“MVC 框架”主导的领域。如果您想了解“MVC 的基本要素”,您必须了解基本要素是关注点分离之类的东西,它们非常重要。

    您问题中的很多文字都提出了一些关于模型应该是什么的混合想法,所以我将把您重定向到关于 MVC 模型的the most linked-to answer。该答案包含您想了解的有关模型概念的所有信息。总结其中最重要的概念,模型不是一个类,它是一个层。模型层有许多组件,它们都做自己的事情,这为您留下了一个可测试、可扩展、语义和逻辑的领域逻辑层。

    请记住要小心:关于 MVC 的错误信息比可靠信息要多得多。要学习正确的 MVC,您可以做的最糟糕的事情就是查看自称是 MVC 的框架。

    编辑:我在响应时假设语言是 PHP,所以我的一些回答可能反映了这个假设。然而,这些概念几乎适用于所有语言

    【讨论】:

    • 我查看了您提供的链接(这太棒了,顺便说一句),但我仍然想知道:一旦“服务”完成了将域对象与一个或更多 Data Mappers,Service 返回什么?如果服务返回完全充实的域对象是否可以,还是应该返回其他内容?
    • @ClaytonRoth 这有点值得商榷。从模型层返回域对象会非常方便,但是您会故意将域逻辑泄漏到模型层之外。理想的解决方案,虽然最初涉及很多,但将这些域对象转换为类似Data Transfer Objects 的东西,可以在整个应用程序中使用。问题是您需要维护两个容器类,如果代码库足够大,这可能会发展成更严重的问题。
    • 我看了一些数据传输对象,看起来每个人都同意 DTO 确实增加了容器类。您是否认为可接受的中间立场是使用通用的 Transformation 类来创建序列化对象的 XML 表示?使用反射,您只需要创建一个类,可能还有一些方法来调整输出,并且您仍然可以拥有服务层隔离。
    • 如果您想完全避免编写特定的 DTO,则可以选择通用 DTO 或 DTO 自动映射器。两种解决方案都是维护 DTO DO的捷径,但是匿名/通用 DTO 是数组上方的一个(小)逻辑步骤,因此您必须评估它是否智能将另一个通用数据结构添加到应用程序中。就我个人而言,我更喜欢编写特定的 DTO,只是为了 100000% 确保一切都完全按计划在另一边出现。
    【解决方案2】:

    该应用程序是一个财务跟踪应用程序。我被困在第一页,这只是本月银行账户交易的列表。 事务列表是我的模型。此时控制器和视图很容易想象。

    您网页上的所有内容都归类在“查看”域中。 “列表”是一个视觉对象。

    对于 Web 应用程序/页面,模型存在于您的服务器上,在您的数据库中。网页上存在的所有内容(按钮、表单、列表框等)都是您的查看域。

    从我读过的大部分内容来看,数据库访问应尽可能封装在模型中,在控制器和视图中几乎没有数据库访问。

    传统上,视图对象直接与您的模型对象对话。这意味着您必须为您的 View 对象提供一种与数据库对话的方式。

    一个例子,

    • http//server/transactions(获取所有交易)
    • http//server/transactions?from=x(从 x 获取交易)
    • http//server/transactions?from=x&to=y(获取从 x 到 y 的交易)

    可能是您的视图与模型的接口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 2015-12-01
      • 1970-01-01
      • 2021-09-18
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多