Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NET MVC-控制器中是否应存在业务逻辑?_Asp.net Mvc_Design Patterns_Controller_Business Logic - Fatal编程技术网

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

Asp.net mvc ASP.NET MVC-控制器中是否应存在业务逻辑?,asp.net-mvc,design-patterns,controller,business-logic,Asp.net Mvc,Design Patterns,Controller,Business Logic,德里克·惠特克(Derik Whitaker)几天前发布了一篇文章,其中提到了一个我一直很好奇的问题:控制器中是否应该存在业务逻辑? 到目前为止,我看到的所有ASP.NET MVC演示都将存储库访问和业务逻辑放在了控制器中。有些人甚至在那里也加入了验证。这会导致相当大、臃肿的控制器。这真的是使用MVC框架的方式吗?似乎这将导致大量重复的代码和逻辑分散在不同的控制器上。业务逻辑应该真正在模型中。你应该瞄准肥胖的模特,瘦小的控制器 例如,与其拥有: public interface IOrderSe

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


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

业务逻辑应该真正在模型中。你应该瞄准肥胖的模特,瘦小的控制器

例如,与其拥有:

public interface IOrderService{
    int CalculateTotal(Order order);
}
我宁愿:

public class Order{
    int CalculateTotal(ITaxService service){...}        
}
这假设税是由外部服务计算的,并要求您的模型了解与外部服务的接口

这将使控制器看起来像:

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

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

或者类似的问题。

这是一个有趣的问题

我认为有趣的是,大量示例MVC应用程序实际上没有遵循MVC范式,即真正将“业务逻辑”完全放在模型中。Martin Fowler指出MVC不是四人帮意义上的模式。相反,如果程序员正在创建玩具应用程序之外的东西,那么他们必须向其中添加模式

因此,简单的回答是“业务逻辑”实际上不应该存在于控制器中,因为控制器具有处理视图和用户交互的附加功能,并且我们希望创建具有唯一目的的对象


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

您可以查看斯蒂芬·沃尔特(Stephen Walther)的精彩教程

了解如何移动验证 控制器操作的逻辑 并进入一个单独的服务层。在里面 本教程由Stephen Walther编写 解释如何保持锋利的牙齿 通过隔离来分离关注点 从您的 控制器层


我喜欢你展示的图表。我相信“一幅画抵得上千言万语”这句格言


控制器中不应包含业务逻辑。控制器应尽可能薄,理想情况下遵循以下模式:

  • 查找域实体
  • 对域实体采取行动
  • 为查看/返回结果准备数据
  • 此外,控制器还可以包含一些应用程序逻辑

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

    什么是模型?这是个好问题。请参阅(AlejandroR的出色发现)。这里有三类模型:

    • 视图模型:这只是一个数据包,如果有逻辑的话,可以将数据从视图传递到视图,包含基本的字段验证
    • 域模型:具有业务逻辑的Fat模型,在单个或多个数据实体上运行(即实体a处于给定状态,而不是实体B上的操作)
    • 数据模型:存储感知模型,单个实体中包含的逻辑仅与该实体相关(即,如果字段a,则字段b)
    当然,MVC是一个有不同种类的范例。我在这里描述的是MVC只占据顶层,参见

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


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

    那么您会将服务注入控制器而不是存储库吗?在这种情况下,单位功原理是如何发挥作用的?我写了更多的东西,我希望这更有意义。您可能还想读一读:尽管它是关于Rails的,但它仍然非常适用。我个人将存储库称为服务。它们肯定是一种服务,但专门用于数据访问。这只是我使用的一种约定,不是我特别提倡的。这将使您的模型与ITaxService紧密耦合。如果您想在另一个项目或其他dll中重用模型,您必须拥有ITaxService实现或引用,否则您的模型将被破坏,这将违反坚实的原则。ITaxService应该有您的模型的引用。通过这种方式,您可以在其他项目中重用您的模型,而无需ITaxService引用。这非常有用!你能告诉我你在那个网站的什么地方找到了这个图表吗?这是微软的“服务器端实现”好的,但是在一个MVC应用程序中——业务逻辑在哪里?似乎我们需要一个额外的服务层或什么?!这是最正确的答案。我个人进一步主张不要向控制器公开服务,而是选择使用MVVM模式中的ViewModel概念。设想一个场景,在这个场景中,您希望编写一个具有桌面界面(例如,windows窗体或WPF)和web界面的业务应用程序。解决这个问题会导致您使用“瘦控制器”模式,这里也提倡这种模式。一句话:永远不要把业务逻辑放在模型或控制器中,也不要把你没有的东西放在控制器中。这篇文章的链接是死的——是ar的副本