Derik Whitaker几天前发布了一个article,这段时间我已经好奇了一段时间:控制器中是否存在业务逻辑?
到目前为止,我见过的所有ASP.NET MVC演示都将存储库访问和业务逻辑放在控制器中。有些甚至在那里抛出验证。这会导致相当大的膨胀控制器。这真的是使用MVC框架的方式吗?看起来这最终会导致很多重复的代码和逻辑分散在不同的控制器上。
答案 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提供的图表。而且我相信格言“一张图片胜过千言万语”。
答案 2 :(得分:14)
这是一个引人入胜的问题。
我认为有趣的是,大量的示例MVC应用程序实际上无法遵循MVC范例,因为它真正将“业务逻辑”完全置于模型中。 Martin Fowler指出,MVC不是四人帮意义上的模式。相反,如果程序员在玩具应用程序之外创建某些东西,则必须将模式添加到。
因此,简短的回答是“业务逻辑”确实不应该存在于控制器中,因为控制器具有处理视图和用户交互的附加功能,并且我们想要创建只有一个目的的对象。
更长的答案是,在将逻辑从控制器移动到模型之前,您需要考虑模型层的设计。也许您可以使用REST处理所有应用程序逻辑,在这种情况下,模型的设计应该相当清楚。如果没有,您应该知道将使用什么方法来防止模型变得臃肿。
答案 3 :(得分:14)
您可以查看Stephen Walther撰写的这个精彩教程,其中显示了Validating with a Service Layer。
了解如何移动验证 逻辑超出你的控制器动作 并进入一个单独的服务层。在 本教程,Stephen Walther 解释了如何保持敏锐 通过隔离来分离关注点 你的服务层 控制器层。
答案 4 :(得分:8)
业务逻辑不应包含在控制器中。控制器应该尽可能的瘦,理想情况下遵循模式:
此外,控制器可以包含一些应用程序逻辑。
那么我在哪里放置我的业务逻辑?在模型中。
什么是模特?现在这是一个很好的问题。请参阅Microsoft Patterns and Practices article(感谢AlejandroR的优秀发现)。在这里有三类模型:
当然,MVC是一种不同种类的范例。我在这里描述的是MVC仅占用顶层,视频this article on Wikipedia
今天,MVC和类似的模型 - 视图 - 展示者(MVP)是Separation of Concerns设计模式,它们专门适用于更大系统的表示层。在简单的场景中,MVC可以代表系统的主要设计,直接进入数据库;但是,在大多数情况下,MVC中的Controller和Model对服务或数据层/层都有松散的依赖性。这完全是关于客户端 - 服务器架构
答案 5 :(得分:-1)
如果您使用依赖注入器,您的业务逻辑将转移到它们,因此您将获得整洁干净的控制器。