数据访问层应该包含业务逻辑吗?

20

我注意到一种趋势,即将业务逻辑从数据访问层(如存储过程、LINQ等)移至业务逻辑组件层(例如C#对象)。

这是否被视为现在“正确”的做法?如果是这样,这是否意味着一些数据库开发人员职位可能会被取代,转而更多地聘用中间层编码人员?(例如更多的C#代码,而不是更长的存储过程。)


相关:https://sites.google.com/site/unclebobconsultingllc/active-record-vs-objects - jaco0646
12个回答

33
如果应用程序很小且生命周期短,则不值得花时间将关注点抽象成层。在更大、更长寿命的应用程序中,逻辑/业务规则不应与数据访问耦合。随着应用程序的增长,这会创建一个维护噩梦。
将关注点移动到公共层或也称为关注点分离已经存在一段时间: 维基百科 引用: 术语“分离关注点”可能是由Edsger W. Dijkstra在他的1974年论文“论科学思想的作用”的1中创造的。
对于应用程序架构,一个很好的起点是领域驱动设计。Eric Evans详细介绍了应用程序的不同层。他还讨论了数据库阻抗以及他所谓的“有界上下文”。 有界上下文 博客是一个按最新到最旧显示帖子以便人们评论的系统。有些人会将其视为一个系统或一个“有界上下文”。如果您订阅DDD,则会说博客中有两个系统或两个“有界上下文”:评论系统和发布系统。DDD认为每个系统是独立的(当然两者之间会有互动),并应该进行相应的建模。DDD提供了如何将关注点分离到适当层的具体指导。

其他可能会对您感兴趣的资源:

在我有机会体验大面团代码意大利面代码之前,我很难理解为什么应用程序架构如此重要...

做事情的正确方式始终取决于您的应用程序的规模、可用性要求和寿命。对于中小型项目,像nHibernate和Linq to SQL这样的工具非常棒。为了让自己清楚,我从未在大型应用程序上使用过nHibranate或Linq To Sql,但我的直觉是,应用程序将达到一定规模,需要通过视图、存储过程等在数据库服务器上进行优化,以保持应用程序的性能。为了完成这项工作,需要具备开发和数据库技能的开发人员。


2
在与一些更复杂的架构密切合作后,我可以说这是一个比我的答案好得多的答案。 - Matthew Olenik
在Asp.net MVC4中,我使用了区域(Areas)。每个区域都是一个支持主应用程序封装的整个过程的小应用程序。每个区域都有自己的数据访问层(DAL)和业务层来获取DAL方法。对于类似的DAL方法,我尝试将其放在应用程序的主要区域之外(即区域之外)。我注意到,我开始将业务逻辑添加到DAL中,以处理事务编辑,因为我想避免打开和关闭多个连接,同时确保满足条件。如果这样做,是否可以将其包含在MVC应用程序的小区域内? - eaglei22
我只有几年的实际经验,所以虽然我仍在掌握编码技能,但我也在努力学习最佳设计和架构实践。我还没有完全掌握,但随着我接手从零开始构建项目的任务,我被迫快速学习。 - eaglei22

18

数据访问逻辑应该在数据访问层中,业务逻辑应该在业务层中。从设计角度来看,我不认为将两者混合在一起可以被视为一个好主意。


5
也许不是这样,但这并不排除使用存储过程构建业务层,也不强制使用 C# 代码。 - Tony Andrews
1
当然不是。在某些情况下,可能需要使用存储过程来处理业务逻辑,但这会付出一定的代价。您应该尽可能保持层之间的分离。 - Matthew Olenik
我真的不太明白数据访问和"业务"之间的区别。 - Seun Osewa
2
对于任何未来的读者,请谨慎遵循这个建议。这非常接近贫血领域模型。与Foo相关的方法应该在Foo的模型中。除非你有充分的理由,否则不要将实体留作一堆getter和setter,并将它们的方法放在另一个层中。这是在过去一年里与一些更复杂的系统密切合作后学到的教训。 - Matthew Olenik

4

分层并不意味着业务逻辑不能使用存储过程。以下是一种可行的分层方式:

表现层:.Net、PHP或其他

业务层:存储过程

数据层:存储过程或DML

例如在Oracle中,这种方式非常有效,因为业务层可以在与数据层不同的模式中以包的形式实现(以强制执行关注点分离)。

重要的是关注点的分离,而不是每个层级所使用的语言/技术。

(我预计会因此被猛烈抨击!)


1
在净化之火中燃烧吧,你这个异端!:0) (+1) - willcodejavaforfood
1
你可能是一个控制狂(即数据库管理员),喜欢一切都在你的掌控之下 :-) 如果你能将GUI层移动到数据库中,你可能也会这样做! - joedotnot
2
@joedotnot - 有趣的是你这么说:我使用Oracle Application Express,它从数据库中保存的元数据生成HTML页面。太棒了! - Tony Andrews
这三条评论在一个阴沉的周二晚上给了我很大的鼓励——谢谢你们,伙计们! - whytheq

3
完美的世界并不存在,重要的是优雅与实用之间的平衡。在数据访问层中执行复杂的SQL查询比多次请求数据并合并和转换它们更具性能优势。当您制作复杂的查询时,您将业务逻辑放入这些查询中。

1

这真的取决于需求。无论哪种方式,只要它不是“在按钮后面”,我认为存储过程对于具有不断变化需求的“经典”客户端服务器应用程序更好。严格的中间“业务逻辑”层对于需要非常可扩展、运行在多个数据库平台等应用程序更好。


1

如果您正在构建分层架构,并且该架构包含专用业务层,则当然应该将业务逻辑放在那里。但是,您可以询问任何五个设计师/架构师/开发人员“业务逻辑”实际上是什么,并获得六个 不同的 答案。(嘿,我自己就是一名架构师,所以我知道所有关于“一方面,另一方面”的事情!)。导航对象图是数据层还是业务层的一部分?这取决于您使用的EAA模式以及您的域对象有多么复杂/聪明。或者它甚至是您的演示文稿的一部分吗?

但更具体地说:数据库开发工具往往落后于Eclipse/Visual Studio/Netbeans;而存储过程对于大规模开发来说从未非常舒适。是的,当然你可以用TSQL、PL/SQL等编写所有代码,但这是有代价的。此外,在一个解决方案中涉及多种语言和平台的成本会增加维护成本和延迟。另一方面,将数据访问移出DBA的控制范围可能会引起其他问题,特别是在具有任何可用性要求的共享基础设施环境中。但总的来说,现代工具和语言目前正在将逻辑从数据(库)层移动到应用程序层。我们将看到它的实际效果和扩展性如何。


0

在规划业务规则的撰写位置时,还需要考虑技术原因/限制。

在大多数LOB应用程序中,集中和性能推动开发人员将数据库本身用作主要的业务层,因此,在某种程度上,DAL和BL被混合或统一了。

一个典型的例子是计算租赁物品当前位置的字段,这是一个应该为一个或多个列出的项目提供的信息,使用带有用户定义函数的SQL视图是保存规则的最强大的候选项。

当然,上述示例仅在首选特定数据库设计和流程实现时才有效,但我想指出的是,在现实世界中,我们更常根据技术限制和其他原则进行选择,而不是组织我们的代码。


0
我看到这种趋势的原因是LINQ和LINQ to SQL ORM为您提供了一种很好的类型安全的替代存储过程的选择。
“正确”的是你个人是否从中受益。

0

是的,业务逻辑应该放在业务逻辑层。对我来说,使用存储过程处理所有事情,并将一些业务规则移动到数据库中是最大的缺点,我更喜欢将这个逻辑放在业务逻辑层(BLL),只让数据访问层(DLL)与数据库进行通信。


0

将你的层分离开始终是个好主意。我无法告诉你有多少次我看到存储过程非常复杂,因为很多业务逻辑都写在了存储过程中。此外,如果您出于任何原因修改了复杂的存储过程,则有可能破坏使用它的所有内容。

我们公司的开发人员正在转向使用LINQ和EF,并且除非我们绝对需要它,否则不再使用存储过程。当EF没有困难时,LINQ和EF使我们更容易分离层...但这又是另一个故事了。 :)


EF是否与数据访问层解耦?还是说EF就是数据访问层本身?ORM创建对象,这些对象的创建是否与实际业务逻辑不同? - whytheq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接