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

时间:2008-10-24 20:57:03

标签: asp.net-mvc design-patterns controller business-logic

Derik Whitaker几天前发布了一个article,这段时间我已经好奇了一段时间:控制器中是否存在业务逻辑?

到目前为止,我见过的所有ASP.NET MVC演示都将存储库访问和业务逻辑放在控制器中。有些甚至在那里抛出验证。这会导致相当大的膨胀控制器。这真的是使用MVC框架的方式吗?看起来这最终会导致很多重复的代码和逻辑分散在不同的控制器上。

6 个答案:

答案 0 :(得分:75)

业务逻辑应该真的在模型中。你应该瞄准脂肪模型,瘦小的控制器。

例如,而不是:

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);
    }
}

或类似的东西。

答案 1 :(得分:63)

我喜欢Microsoft Patterns & Practices提供的图表。而且我相信格言“一张图片胜过千言万语”。

Diagram shows architecture of MVC and business sevices layers

答案 2 :(得分:14)

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

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

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

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

答案 3 :(得分:14)

您可以查看Stephen Walther撰写的这个精彩教程,其中显示了Validating with a Service Layer

  

了解如何移动验证   逻辑超出你的控制器动作   并进入一个单独的服务层。在   本教程,Stephen Walther   解释了如何保持敏锐   通过隔离来分离关注点   你的服务层   控制器层。

答案 4 :(得分:8)

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

  1. 查找域名实体
  2. 域名实体法案
  3. 为查看/返回结果准备数据
  4. 此外,控制器可以包含一些应用程序逻辑。

    那么我在哪里放置我的业务逻辑?在模型中。

    什么是模特?现在这是一个很好的问题。请参阅Microsoft Patterns and Practices article(感谢AlejandroR的优秀发现)。在这里有三类模型:

    • 查看模型:这只是一个数据包,只有极小的(如果有的话)逻辑可以从视图传递数据,包含基本的字段验证。
    • 域模型:具有业务逻辑的胖模型,对单个或多个数据实体(即给定状态下的实体A而非实体B上的操作)进行操作。
    • 数据模型:存储感知模型,单个实体中包含的逻辑仅与该实体相关(即如果字段a则为字段b)

    当然,MVC是一种不同种类的范例。我在这里描述的是MVC仅占用顶层,视频this article on Wikipedia

      

    今天,MVC和类似的模型 - 视图 - 展示者(MVP)是Separation of Concerns设计模式,它们专门适用于更大系统的表示层。在简单的场景中,MVC可以代表系统的主要设计,直接进入数据库;但是,在大多数情况下,MVC中的Controller和Model对服务或数据层/层都有松散的依赖性。这完全是关于客户端 - 服务器架构

答案 5 :(得分:-1)

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