【问题标题】:Where do I put this logic in this simple MVC scenario?在这个简单的 MVC 场景中,我应该把这个逻辑放在哪里?
【发布时间】:2014-07-23 23:21:30
【问题描述】:

我将描述我必须解决的问题,然后提出我的问题。

问题

我的问题很简单,至少看起来是这样。我需要访问数据库,并取回一组运动交易实体。其中包括“丹佛掘金队将 PlayerX 换成 PlayerY”之类的内容。一旦我有了事务实体的集合,我需要将内容以特定格式输出到 .txt 文件,大致如下:

Title
  Sport1
    League1
      Transaction1
      Transaction2
      ...
    League2
      Transaction1
      Transaction2
  Sport2
  etc.

运动和联赛的顺序很重要。首先是棒球,然后是足球等。如果一项运动没有交易,则该运动的文件中不包含任何内容。程序差不多就是这样。

我正在使用 ORM,Transaction 实体非常大,有很多我不需要显示的额外字段。出于这个原因,我想映射到仅包含上述信息的视图模型。

问题

首先,这里没有“域”,因此不需要分解的域事务对象,对吧?我需要做的就是从数据库实体映射到 ViewModel?

其次,我在存储库方法调用中编码了多少“视图”逻辑?我是否会取回事务实体的集合,然后在我的控制器中对它们进行排序?或者存储库应该为我做这个排序吗?我觉得如果我让存储库类根据视图需要它们的顺序对我的事务进行排序,那么这会传播视图逻辑,这很令人困惑。另一方面,让数据库进行排序会带来性能优势。

第三,控制器在构建视图模型方面做了多少工作?例如,就像我上面所说的,任何没有交易的运动都不应该显示。控制器应该检查这些事务并从视图模型中明确排除,还是应该由视图进行检查和决定?

感谢您抽出宝贵时间回复。

【问题讨论】:

  • 基本上,您定义应用程序的业务/视图逻辑含义。如果订单或可见性是您的应用程序的主要功能,我不会认为它是视图逻辑。在我看来,即使是 DB 排序也可以。

标签: oop model-view-controller mvvm viewmodel


【解决方案1】:

首先,这里没有“域”,因此不需要分解 域事务对象,对吧?我需要做的就是从 数据库实体到 ViewModel?

我觉得不错

其次,我在存储库方法中编码了多少“视图”逻辑 称呼?我是否要取回事务实体的集合,然后 在我的控制器中对它们进行排序?或者存储库是否应该进行这种排序 为了我?我觉得如果我让存储库类对我的交易进行排序 根据我需要它们查看的顺序,然后传播 查看周围的逻辑,这是令人困惑的。另一方面,有一个 让数据库进行排序可以提高性能。

我认为在数据库中排序是可以的,因为它对性能更好。多少“观”?取决于视图。看下一个答案。

第三,控制器在构造方面做了多少工作 视图模型?例如,就像我上面所说的,任何没有 根本不应该显示交易。如果控制器 检查并从视图模型中明确排除这些事务, 还是视图应该做出检查和决定?

您正在转储为文本,因此此处的“查看”只是您将添加到缩进中的制表符或空格的数量。但是如果它是一个 GUI 树组件呢?然后您必须将数据推送到节点并提供有关哪个节点是哪个节点的子节点的信息,然后您就可以为您的控制器工作了。

我认为 MVC 的主要思想是更容易切换每个组件。我的意思是,如果将典型的树可视化从纯文本替换为 GUI 树组件很容易,那么您的 MVC 设计得很好。如果不是,则可能这些层仍然过于耦合,您无法正确重用其他层。

【讨论】:

  • 您提出了一个很好的观点,我需要听到:如果某些事情很难改变,那么它可能可以通过重构来实现。如果很容易做出改变,那么它可能没问题。我一直希望软件开发中的每个问题都有一个可重复的解决方案,但我越来越意识到问题的背景决定了最佳解决方案。
【解决方案2】:

首先,这里没有“域”,因此不需要分解 域事务对象,对吧?我需要做的就是从 数据库实体到 ViewModel?

您是指数据传输对象 (DTO) 吗?如果您跨越边界,您可能仍然需要它们(即 db > repository > webservice > repository > your app)。从 Web 服务到您的应用程序,您跨越边界,因此您可能需要 DTO 来减少数据。

其次,我在存储库方法中编码了多少“视图”逻辑 称呼?我是否要取回事务实体的集合,然后 在我的控制器中对它们进行排序?或者存储库是否应该进行这种排序 为了我?我觉得如果我让存储库类对我的交易进行排序 根据我需要它们查看的顺序,然后传播 查看周围的逻辑,这是令人困惑的。另一方面,有一个 让数据库进行排序可以提高性能。

存储库应该用于获取数据。是否在存储库中使用排序取决于您想要做什么。

您是否只想先按“体育”排序,然后按“联赛”排序,然后按“交易日期”排序?然后在仓库里做就可以了,ihmo。

你想让它把你的数据变成一个树形结构吗?那就不要。这应该封装在服务中。该服务接收您的存储库的一个实例,您的服务中可能有一个public PlayerTransactionsViewModel PlayerTransactionsService.GetAllTransactions() 或类似的东西。然后,该服务会查询所有交易数据并将其转换为您的 ViewModel

第三,控制器在构造方面做了多少工作 视图模型?例如,就像我上面所说的,任何没有 根本不应该显示交易。如果控制器 检查并从视图模型中明确排除这些事务, 还是视图应该做出检查和决定?

控制器动作应该非常小并且主要包装对视图的调用。除了分配一些值(即从 Service 映射到 ViewModel...,除非您的服务当然已经返回 ViewModel)之外,您根本不应该有任何构造逻辑。

这里可能需要使用数据传输对象,以减少从存储库获取并传递给服务的数据。

在回答第二个问题时,您应该使用服务来封装来自控制器的逻辑并将您的控制器限制为简单的调用

PlayerTransactionsViewModel viewModel = playerTransactionService.GetAllTransactions();
return View(viewModel);

但是由于您正在编写一个文本文件(我假设是文件系统),实际上根本不涉及任何视图,您也可以在服务中这样做

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 2011-04-20
    • 2014-02-27
    相关资源
    最近更新 更多