asp.net-mvc ASP.NET MVC - 控制器中是否应该存在业务逻辑?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/235233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 22:49:21  来源:igfitidea点击:

ASP.NET MVC - Should business logic exist in controllers?

asp.net-mvcdesign-patternscontrollerbusiness-logic

提问by Kevin Pang

Derik Whitaker posted an articlea couple of days ago that hit a point that I've been curious about for some time: should business logic exist in controllers?

德里克·惠特克(Derik Whitaker)几天前发表了一篇文章,其中提到了一个我一直很好奇的观点:控制器中应该存在业务逻辑吗?

So far all the ASP.NET MVC demos I've seen put repository access and business logic in the controller. Some even throw validation in there as well. This results in fairly large, bloated controllers. Is this really the way to use the MVC framework? It seems that this is just going to end up with a lot of duplicated code and logic spread out across different controllers.

到目前为止,我看到的所有 ASP.NET MVC 演示都将存储库访问和业务逻辑放在控制器中。有些人甚至还会在那里进行验证。这会导致相当大的、臃肿的控制器。这真的是使用MVC框架的方式吗?似乎这最终会导致大量重复的代码和逻辑分布在不同的控制器上。

采纳答案by jonnii

Business logic should really be in the model. You should be aiming for fat models, skinny controllers.

业务逻辑确实应该在模型中。你应该瞄准胖模型,瘦控制器。

For example, instead of having:

例如,而不是:

public interface IOrderService{
    int CalculateTotal(Order order);
}

I would rather have:

我宁愿有:

public class Order{
    int CalculateTotal(ITaxService service){...}        
}

This assumes that tax is calculate by an external service, and requires your model to know about interfaces to your external services.

这假设税是由外部服务计算的,并且需要您的模型了解外部服务的接口。

This would make your controller look something like:

这将使您的控制器看起来像:

public class OrdersController{
    public OrdersController(ITaxService taxService, IOrdersRepository ordersRepository){...}

    public void Show(int id){
        ViewData["OrderTotal"] = ordersRepository.LoadOrder(id).CalculateTotal(taxService);
    }
}

Or something like that.

或类似的东西。

回答by AlejandroR

I like the diagram presented by Microsoft Patterns & Practices. And I believe in the adage 'A picture is worth a thousand words'.

我喜欢Microsoft Patterns & Practices提供的图表。我相信“一张图片胜过一千个字”这句格言。

Diagram shows architecture of MVC and business sevices layers

该图显示了 MVC 和业务服务层的架构

回答by Joe Soul-bringer

This is a fascinating question.

这是一个引人入胜的问题。

I think that its interesting that a large number of sample MVC applications actually fail to follow the MVC paradigm in the sense of truly placing the "business logic" entirely in the model. Martin Fowler has pointed out that MVC is not a pattern in the sense of the Gang Of Four. Rather, it is paradigm that the programmer must add patterns toif they are creating something beyond a toy app.

我认为有趣的是,在真正将“业务逻辑”完全置于模型中的意义上,大量示例 MVC 应用程序实际上未能遵循 MVC 范式。Martin Fowler 指出 MVC 不是四人组意义上的模式。相反,如果程序员要创建玩具应用程序以外的东西则必须为其添加模式。

So, the short answer is that "business logic" should indeed not live in the controller, since the controller has the added function of dealing with the view and user interactions and we want to create objects with only one purpose.

因此,简短的回答是“业务逻辑”确实不应该存在于控制器中,因为控制器具有处理视图和用户交互的附加功能,而我们只想创建只有一个目的的对象。

A longer answer is that you need to put some thought into the design of your model layer before just moving logic from controller to model. Perhaps you can handle all of app logic using REST, in which case the model's design should be fairly clear. If not, you should know what approach you are going to use to keep your model from becoming bloated.

更长的答案是,在将逻辑从控制器移动到模型之前,您需要对模型层的设计进行一些思考。也许您可以使用 REST 处理所有应用程序逻辑,在这种情况下,模型的设计应该相当清晰。如果没有,您应该知道将使用什么方法来防止模型变得臃肿。

回答by Leniel Maccaferri

You can check this awesome tutorial by Stephen Walther that shows Validating with a Service Layer.

您可以查看 Stephen Walther 的这个很棒的教程,其中显示了使用服务层进行验证

Learn how to move your validation logic out of your controller actions and into a separate service layer. In this tutorial, Stephen Walther explains how you can maintain a sharp separation of concerns by isolating your service layer from your controller layer.

了解如何将验证逻辑从控制器操作中移到单独的服务层中。在本教程中,Stephen Walther 解释了如何通过将服务层与控制器层隔离来保持关注点的清晰分离。

回答by Jacek Glen

Business Logic should not be contained in controllers. Controllers should be as skinny as possible, ideally follow the patter:

业务逻辑不应包含在控制器中。控制器应该尽可能瘦,最好遵循以下模式:

  1. Find domain entity
  2. Act on domain entity
  3. Prepare data for view / return results
  1. 查找域实体
  2. 作用于域实体
  3. 为查看/返回结果准备数据

Additionally controllers can contain some application logic.

此外,控制器可以包含一些应用程序逻辑。

So where do I put my business logic? In Model.

那么我应该把我的业务逻辑放在哪里呢?在模型中。

What is Model? Now that's a good question. Please see Microsoft Patterns and Practices article(kudos to AlejandroR for excellent find). In here there are three categories of models:

什么是模型?这是个好问题。请参阅Microsoft 模式和实践文章(感谢 AlejandroR 的出色发现)。这里有三类模型:

  • View Model: This is simply a data bag, with minimal, if any, logic to pass data from and to views, contains basic field validation.
  • Domain Model: Fat model with business logic, operates on a single or multiple data entities (i.e. entity A in a given state than action on entity B)
  • Data Model: Storage-aware model, logic contained within a single entity relates only to that entity (i.e. if field a then field b)
  • 视图模型:这只是一个数据包,具有从视图传递数据和向视图传递数据的最小逻辑(如果有的话),包含基本的字段验证。
  • 领域模型:具有业务逻辑的胖模型,对单个或多个数据实体进行操作(即处于给定状态的实体 A 而不是对实体 B 的操作)
  • 数据模型:存储感知模型,单个实体中包含的逻辑仅与该实体相关(即如果字段 a 则字段 b)

Of course, MVC is a paradigm that comes in different varieties. What I describe here is MVC occupying top layer only, vide this article on Wikipedia

当然,MVC 是一个有不同种类的范式。我这里描述的是MVC只占用顶层,请参阅维基百科上的这篇文章

Today, MVC and similar model-view-presenter (MVP) are Separation of Concerns design patterns that apply exclusively to the presentation layer of a larger system. In simple scenarios MVC may represent the primary design of a system, reaching directly into the database; however, in most scenarios the Controller and Model in MVC have a loose dependency on either a Service or Data layer/tier. This is all about Client-Server architecture

今天,MVC 和类似的模型-视图-展示器 (MVP) 是关注点分离设计模式,专门应用于更大系统的展示层。在简单的场景中,MVC 可能代表系统的主要设计,直接进入数据库;然而,在大多数情况下,MVC 中的控制器和模型对服务或数据层/层具有松散的依赖性。这完全是关于客户端 - 服务器架构

回答by chandresh patel

If u use Dependency Injectors your business logic will go to them and hence you will get neat and clean controllers.

如果您使用依赖注入器,您的业务逻辑将转到它们,因此您将获得整洁干净的控制器。