德里克·惠特克 (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);
    }
}

或类似的东西。

其他提示

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

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

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

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

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

您可以查看Stephen Walther撰写的这篇精彩教程,该教程显示使用服务层进行验证

  

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

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

  1. 查找域实体
  2. 作用于域实体
  3. 准备数据以供查看/返回结果

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

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

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

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

当然,MVC 是一种有不同变体的范例。我这里描述的是仅占据顶层的MVC,参见 维基百科上的这篇文章

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top