域驱动设计与MVC Web应用程序的数据库驱动设计

时间:2012-05-21 12:00:47

标签: asp.net-mvc architecture domain-driven-design database-driven

我正在将旧版Web窗体应用程序扩展/转换为全新的MVC应用程序。扩展既包括技术也包括业务用例。遗留应用程序是一个完善的数据库驱动设计(DBDD)。因此对于例如如果你有不同类型的员工,如操作员,主管,商店守护者等,你需要添加一个新类型,你只需要在几个表中添加一些行,瞧,你的UI自动拥有添加/更新新的一切员工类型。 然而,层的分离并不是那么好。

新项目有两个主要目标

  • 可扩展性(针对当前和未来的管道要求)
  • 性能

我打算使用域驱动设计(DDD)创建替换数据库驱动设计(DBDD)的新项目,同时牢记可扩展性要求。但是,如果将其与传统DBDD应用程序的性能进行比较,从数据库驱动设计转向域驱动设计似乎会对性能要求产生相反的影响。在遗留应用程序中,来自UI的任何数据调用都将直接与数据库交互,并且任何数据都将以DataReader或(在某些情况下)DataSet的形式返回。

现在有了严格的DDD,任何数据调用都将通过业务层和数据访问层进行路由。这意味着每次调用都会初始化业务对象和数据访问对象。单个UI页面可能需要不同类型的数据,这是一个Web应用程序,每个页面都可以由多个用户请求。 MVC Web应用程序也是无状态的,每个请求都需要每次都初始化业务对象和数据访问对象。 因此,对于MVC无状态应用程序而言,DBDD更倾向于DDD以提高性能。

或者在DDD中有一种方法可以实现DDD提供的可扩展性和DBDD提供的性能吗?

3 个答案:

答案 0 :(得分:6)

您是否考虑过某种形式的命令查询分离,其中更新是通过域模型进行的,而读取来自DataReader?全面的DDD并不总是合适的。

答案 1 :(得分:4)

  

“现在有了严格的DDD,任何数据调用都将通过业务层和数据访问层进行路由。”

我不相信这是真的,这当然不实际。我相信这应该是:

  

现在有了严格的DDD,任何对交易的呼叫都将通过业务层和数据访问层进行路由。

没有任何内容表明您不能直接调用数据访问层以获取您需要在屏幕上显示的任何数据。只有当您需要修改需要调用基于其行为而设计的域模型的数据时。在我看来,这是一个关键的区别。如果您通过域模型路由所有内容,则会遇到三个问题:

  1. 时间 - 实现功能需要更长的时间,没有任何好处。
  2. 模型设计 - 您的域模型将变形,以满足查询而非行为的需求。
  3. 性能 - 不是因为额外的图层,而是因为您无法直接从查询中获取模型中的聚合数据。考虑为特定客户下达的所有订单的总价值 - 为此编写查询的速度要比为客户获取所有订单实体要快得多,迭代并求和。
  4. 正如Chriseyre2000所提到的,CQRS旨在解决这些问题。

答案 2 :(得分:1)

使用DDD不应该在您的方案中产生重大的性能影响。您担心的问题似乎更像是数据访问问题。你将它称为

  

初始化业务对象和数据访问对象

为什么'初始化'很贵?您使用什么数据访问机制?

使用存储在关系数据库中的长寿命对象的DDD通常使用ORM实现。 如果使用正确,ORM对大多数应用程序的性能影响很小(如果有的话)。如果存在经过验证的瓶颈,您始终可以将应用程序中性能最敏感的部分切换回原始SQL。

对于它的价值,NHibernate只需要在应用程序启动时初始化一次,之后它使用与常规数据读取器相同的ADO.NET连接池。所以这一切归结为一个正确的映射,获取策略并避免经典的数据访问错误,如'n + 1选择'。