你如何保持业务规则干?

时间:2010-03-31 20:00:34

标签: ruby-on-rails database-design dry

在完美的应用程序中,每个业务规则只存在一次。

我在一家商店工作,尽可能在数据库中执行业务规则。在许多情况下,为了获得更好的用户体验,我们在客户端执行相同的验证。不是DRY。作为SPOT纯粹主义者,我讨厌这个。

另一方面,一些商店创建了愚蠢的数据库(Rails社区倾向于这个方向)并将业务逻辑降级到一个单独的层。但即使采用这种方法,一些验证逻辑最终会重复客户端。

为了使问题更加复杂,我理解为什么数据库应该是treated as a fortress,因此我同意在数据库中强制执行/重复验证。

考虑到相互矛盾的问题,尝试在一个地方强制执行验证并不容易 - 保持DRY,保持数据库成为堡垒,并提供良好的用户体验。我有some idea for overcoming this issue,但我想有更好的。

我们能否以干燥的方式平衡这些相互冲突的问题?

6 个答案:

答案 0 :(得分:7)

任何未在其所属的数据库中强制执行所需业务规则的人都将拥有错误的数据,这很简单。数据完整性是数据库的作业。数据库受到比应用程序更多的源的影响,并且仅在应用程序中放置所需的规则是短视的。如果你这样做,你将从导入,连接时的其他应用程序,特殊查询以修复大量数据(想想将所有价格提高10%)等中获取错误数据,等等。执行极端是愚蠢的仅通过申请来规则。但话说回来,我是必须修复进入设计不良的数据库的不良数据的人,应用程序开发人员认为这些数据应该仅在应用程序中执行。

在许多情况下,数据将在应用程序之后很长时间内存在。当这种情况发生时你也会失去规则。

答案 1 :(得分:6)

  

顺便说一句,在一个核心位置存在所有业务逻辑的问题的清晰分离是一个难以维护的乌托邦幻想

看不出原因。

  

处理单独层中的所有业务逻辑(在Rails中,模型将容纳“大部分”)

正确。 Django也这样做。

  

某些业务逻辑最终会溢出到其他地方(在Rails中它可能会溢出到控制器中

不是真的。业务逻辑可以 - 而且应该 - 在模型层中。其中一些将被编码为类,库和其他可在其他地方使用的逻辑捆绑的方法。 Django使用Form对象来验证输入。它们来自模型,但用作前端HTML以及任何批量加载的一部分。

没有理由在其他地方定义业务逻辑。它可以在其他层中使用,但应该在模型中定义。

使用ORM层从模型生成SQL。一切都在一个地方。

  

[database]建立在导致它拒绝不良数据的约束之上

我认为这是对Database As A Fortress帖子的误读。它说“一个可靠的数据模型”,“拒绝不属于的数据,并防止无意义的关系”。这些是简单的声明性引用完整性。

ORM层可以从模型中生成它。

答案 2 :(得分:4)

数据库作为堡垒和单点事实的关注是同一件事。它们不是相互排斥的。因此,没有必要“平衡他们”。

你所谓的“数据库作为堡垒”实际上只是 实现单点真相的可能方式。

“数据库作为堡垒”是一件好事。这意味着数据库迫使任何人不愿意遵守(根据数据库应该遵守的事实)。很多人发现问题(而不是解决方案确实存在),说明了大多数数据库用户如何看待“真相”的重要性(而不是“我有”这个糟糕的对象我需要持久存在,我只是希望数据库能够做到这一点,尽管有任何商业规则。“)。

答案 3 :(得分:0)

模型 - 视图 - 控制器框架是解决此问题的一种方法。 rails社区使用类似的概念......

基本思想是所有业务逻辑都在控制器中处理,并且需要在视图或模型中应用规则,控制器将它们传递给它。

答案 4 :(得分:0)

通常,业务规则远远超过约束集,因此很明显并非所有业务规则都可以放在数据库中。另一方面,HLGEM指出,期望应用程序处理所有数据验证是天真的:我可以从经验中证实这一点。

我认为没有一种很好的方法可以将所有业务规则放在一个地方,并将它们应用于客户端,服务器端和数据库。我在实体级别使用业务规则(因为hibernate在数据库级别重新创建它们)以及服务级别的其余规则。

答案 5 :(得分:0)

数据库作为堡垒对于关系数据库来说是无稽之谈。你需要一个OODB。