将模型代码划分为MVC中的逻辑部分的最佳实践?哪个最好?

时间:2010-09-19 20:39:35

标签: model-view-controller design-patterns

我是MVC的新手但是从我到目前为止学到的东西(例如here,ScottGu),人们应该渴望“瘦的控制器”而不是“胖子”。 除此之外,视图本身就很薄,并且您将在模型中获得很多代码。

所以我的问题是 - 如何将模型中的代码划分为不同的逻辑部分以降低复杂性? 您是否在模型本身内使用数据访问层和业务逻辑层(我猜这仍然会包含大量代码),还是有更好的方法可以做到这一点?

谢谢。

4 个答案:

答案 0 :(得分:10)

我们使用的图层是:

  • 查看(使用强类型视图模型)
  • 控制器
  • 查看模型服务
  • 商业服务
  • 存储库
  • (EF)上下文

视图 - 尽可能薄 - 没有逻辑 - 只显示

视图模型 - 每个视图的强类型 - 不包含实体,只包含我们想要在任何一个视图中的字段。

控制器 - 只是路由和调用VMS。通过路由到错误页面来处理从较低级别冒出的异常。

View Model Services - 创建视图模型并将其解压缩到EF实体中。没有数据访问逻辑。每个控制器一个VMS。大量使用AutoMapper将视图模型的数据传输到实体中。

商业服务 - 数据访问的主要方面。每个控制器一个BS。使用尽可能多的存储库来完成其工作。交易范围控制器在这里VMS对BS进行一次调用 - 如果需要,它会在单个事务中包装所有必需的DB调用。我们预计BS将来会拨打外部服务电话。

存储库 - 每个(顶级)实体一个 - 为一组实体执行所有CRUD操作。我们的实体是大型复杂的对象图 - 因此我们处理每个存储库的最顶层父级。

上下文 - 围绕EF生成的上下文的瘦包装,这样我们就可以嘲笑它了。

就MVC而言 - 模型部分由控制器下方的所有部分组成。

答案 1 :(得分:3)

以下是我通常将事情分开并建议将事情分开的方法:

  • 模型:代表信息。永远不应该包含与渲染相关的代码。不应包含发布/订阅更新的代码。不应包含读/写代码。

  • 模型I / O:向/从磁盘,网络,SQL或其他某些后备存储读取/写入模型的代码通常应与模型对象本身分开,以允许替代存储。 / p>

  • 控制器基础结构:在模型之上提供一个包装器,用于向模型添加发布/订阅行为(即模型更改时信号更改通知事件)。

  • 控制器:构造模型和视图,从存储加载模型,在模型上注册处理程序以在更改时更新视图。在视图上注册处理程序以在视图操作上更新模型,并在调用保存操作时保存/存储模型。

  • 查看:呈现模型的一个或多个组件。

答案 2 :(得分:3)

我发现的一种方法非常好,就是将模型分离为数据服务层和业务逻辑层。业务逻辑层的基础是那些几乎直接映射到数据库表的对象。然后,数据服务层可以在进行更改或创建新对象时将这些对象直接映射到数据库中。

当我必须处理拒绝整齐地映射到数据库中的单个表的对象时,我将创建一个外观或复合对象,业务逻辑可以通过该对象进行交互。这确保即使它们被业务逻辑视为一个,数据服务层仍然将它们视为不同的,并且只能更新那些需要它的人。

我建议Mapping Objects to the Relational Model上的这篇文章让您入门。

答案 3 :(得分:1)

您可能还想查看可以帮助尝试使控制器尽可能薄的服务层。控制器可以简单地将一些操作委托给服务层执行。通常,此层依赖于数据访问层(DAO),以保持域对象的持久性。在这种情况下,您的控制器很简单,可以协调您的控制流程。 MVC的主要思想是关注点的分离。在传统的MVC中,控制器和视图之间共享的表示逻辑。在MVP(MVC的另一种变体)的情况下,控制器处理所有表示逻辑。