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

发布于 2024-09-19 23:55:37 字数 361 浏览 6 评论 0原文

我是 MVC 新手,但从我到目前为止所学到的知识来看(例如 此处,作者:ScottGu)人们应该追求“瘦控制器”而不是“胖”控制器。
除此之外,视图本质上很薄,您将在模型中获得大量代码。

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

谢谢。

I'm new to MVC but from what I have learned so far (for example here, by ScottGu) one should aspire to "skinny controllers" rather than "fat" ones.
Add to that the fact that views are inherently thin, and you'll get a lot of code in your model.

So my question is - How do you partition the code in your model to different logical parts in order to reduce complexity?
Do you use Data Access Layer and Business Logic Layer within the model itself (which I guess would still hold a lot of code), or are there better ways of doing that?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゝ杯具 2024-09-26 23:55:37

我们使用的层是:

  • 视图(具有强类型视图模型)
  • 控制器
  • 视图模型服务
  • 业务服务
  • 存储库
  • (EF) 上下文

视图 - 尽可能薄 - 无逻辑 - 仅显示

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

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

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

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

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

上下文 - EF 生成的上下文的薄包装器,以便我可以嘲笑它们。

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

The layers we use are:

  • View (with strongly typed View Models)
  • Controller
  • View Model Service
  • Business Services
  • Repositories
  • (EF) Contexts

Views - as thin as can be - no logic - just display

View Models - Strongly typed per view - don't contain Entities, but just the fields we want in any one view.

Controller - just routing and calls to VMS. Handles exceptions that bubble up from the lower levels by routing to error pages.

View Model Services - creates and unpacks view models into the EF entities. No data access logic. One VMS per controller. Makes heavy use of AutoMapper to transfer the view model's data into entities.

Business Services - main point of data access. One BS per controller. Uses as many repositories as required to do its job. Transaction scope controller here. The VMS makes a single call to the BS - which wraps all the necessary DB calls in a single transaction if required. We anticipate the BS making calls out to external services in future.

Repositories - One per (top level) entity - does all CRUD operations for a group of entities. Our entities are large, complex object graphs - so we handle the top-most parent per repository.

Contexts - thin wrappers around the EF generated contexts so they can me mocked.

In terms of MVC - The Model part is made up of everything below the controller.

孤独难免 2024-09-26 23:55:37

以下是我通常如何划分事物并建议划分事物的方式:

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

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

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

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

  • 视图:渲染模型的一个或多个组件。

Here is how I typically divide things up and recommend dividing things up:

  • Model: represents the information. Should never contain rendering-related code. Should not contain code for publishing/subscribing updates. Should not contain reading/writing code.

  • Model I/O: code that reads / writes the model to / from disk, network, SQL, or some other backing store should typically be separate from the model object, itself, to allow for alternative storage.

  • Controller infrastructure: provides a wrapper on top of the model that adds publish / subscribe behavior to the model (i.e. signals change notification events when the model changes).

  • Controller: constructs the model and view, loads the model from storage, registers handlers on the model to update the view when changed. Registers handlers on the view to update the model on view actions and to save / store the model when save actions are invoked.

  • View: one or more components that render the model.

浪推晚风 2024-09-26 23:55:37

我发现一种非常有效的方法是将模型(如您所说)分离为数据服务层和业务逻辑层。业务逻辑层的基础是那些几乎直接映射到数据库表的对象。然后,当发生更改或创建新对象时,数据服务层能够将这些对象直接映射到数据库中。

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

我推荐这篇关于将对象映射到关系模型的文章来帮助您入门。

One way I found works really well is to separate the model, as you say, into a Data Service Layer and a Business Logic Layer. The foundation of the Business Logic layer are those objects with nearly direct mapping to database tables. The Data Service Layer is then able to map these objects directly into the database when changes are made or when new ones are created.

When I have to handle objects that refuse to neatly map to a single table in the database I'll create a facade or composite object through which the business logic can interact. This ensures that even though they are treated as one by the Business Logic the Data Service Layer still sees them as distinct and is able to update only those that need it.

I recommend this article on Mapping Objects to the Relational Model to get you started.

温折酒 2024-09-26 23:55:37

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

You might also want to look at Service Layer that can assist in trying to make controller as thin as possible. The controller can just simply delegate some operations to the service layer for execution. Normally, this layer has a dependency on the Data Access Layer(DAO), for persistence of your domain objects. In this case, your controller is simple there to coordinate your flow of control. The main idea with MVC is the separation of concerns. In the traditional MVC, the presentation logic in shared between your controller and view. In the case on MVP(another variation of MVC), all the presentation logic in handled by the controller.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文