我真的需要看一些关于当前公认的企业应用程序设计范例的优点的诚实,深思熟虑的辩论.
我不相信实体对象应该存在.
实体对象我指的是我们倾向于为我们的应用程序构建的典型事物,如"人","帐户","订单"等.
我目前的设计理念是这样的:
所有数据库访问必须通过存储过程完成.
每当需要数据时,调用存储过程并遍历SqlDataReader或DataTable中的行
(注意:我还使用Java EE构建了企业应用程序,java人员请用等价替换我的.NET示例)
我不是反OO.我为不同的目的写了很多类,而不是实体.我承认我编写的大部分类都是静态助手类.
我不是在建造玩具.我在谈论跨多台机器部署的大型高容量事务应用程序.Web应用程序,Windows服务,Web服务,b2b交互,您可以为其命名.
我使用过OR Mappers.我写了几个.我使用过Java EE堆栈,CSLA和其他一些等价物.我不仅使用它们,而且还在生产环境中积极开发和维护这些应用程序.
我已经得出了经过实战考验的结论,即实体对象正在阻碍我们,如果没有它们,我们的生活会变得如此简单.
考虑这个简单的例子:你得到一个关于你的应用程序中某个页面不能正常工作的支持调用,可能其中一个字段没有像它应该那样持久化.使用我的模型,分配给发现问题的开发人员正好打开3个文件.ASPX,ASPX.CS和带有存储过程的SQL文件.该问题可能是存储过程调用缺少的参数,需要几分钟才能解决.但是对于任何实体模型,您总是会启动调试器,开始逐步执行代码,最终可能会在Visual Studio中打开15-20个文件.当你走到堆栈底部时,你忘记了你的起点.我们一次只能在头脑中保留这么多东西.软件非常复杂,无需添加任何不必要的图层.
开发复杂性和故障排除只是我抱怨的一个方面.
现在让我们谈谈可扩展性.
开发人员是否意识到每次编写或修改与数据库交互的任何代码时,他们都需要对数据库的确切影响进行彻底的分析?而不仅仅是开发副本,我的意思是模仿生产,所以你可以看到你现在需要的对象的附加列只是使当前的查询计划失效,而在1秒内运行的报告现在需要2分钟,因为您在选择列表中添加了一个列?事实证明,您现在需要的索引是如此之大,以至于DBA将不得不修改文件的物理布局?
如果让人们通过抽象让物理数据存储距离太远,他们就会对需要扩展的应用程序造成严重破坏.
我不是狂热者.我可以确信我是否错了,也许我是,因为Linq对Sql,ADO.NET EF,Hibernate,Java EE等有如此强烈的推动.请通过您的回答思考,如果我遗漏了一些东西我我真的想知道它是什么,为什么我应该改变我的想法.
[编辑]
看起来这个问题突然再次激活,所以现在我们有了新的评论功能,我直接评论了几个答案.感谢回复,我认为这是一个健康的讨论.
我可能应该更清楚我正在谈论企业应用程序.我真的不能评论一个在某人的桌面或移动应用程序上运行的游戏.
有一点我必须在顶部提出以回应几个类似的答案:正交性和关注点分离经常被引用作为实体/ ORM的理由.对我来说,存储过程是我能想到的关注点分离的最好例子.如果您不允许除了通过存储过程之外的所有其他数据库访问,理论上您可以重新设计整个数据模型而不破坏任何代码,只要您维护存储过程的输入和输出即可.它们是按合同编程的完美示例(只要您避免"select*"并记录结果集).
询问那些已经在这个行业工作了很长时间并且使用过长期应用程序的人:在数据库存在的时候,有多少应用程序和UI层已经出现了?当有4个或5个不同的持久层生成SQL来获取数据时,调整和重构数据库有多难?你什么都不能改变!ORM或任何生成SQL的代码都会锁定您的数据库.
我认为这取决于应用程序的"逻辑"有多复杂,以及您实现它的位置.如果您的所有逻辑都在存储过程中,并且您的所有应用程序都在调用这些过程并显示结果,那么开发实体对象确实是浪费时间.但是对于对象具有彼此丰富的交互的应用程序,并且数据库只是一种持久性机制,拥有这些对象可能是有价值的.
所以,我会说没有一个通用的答案.开发人员确实需要意识到,有时候,尝试过于OO会导致更多问题而不是解决问题.
理论说,高度凝聚力,松散耦合的实现是前进的方向.
所以我想你正在质疑这种方法,即分离问题.
我的aspx.cs文件是否应该与数据库交互,调用sproc并理解IDataReader?
在团队环境中,特别是在技术人员处理应用程序的aspx部分的情况下,我不需要这些人能够"触摸"这些东西.
将我的域名与数据库分开可以保护我免受数据库中的结构变化的影响,这当然是一件好事吗?确保数据库功能绝对重要,所以让那些最优秀的人在一个地方处理这些东西,对系统其他部分的影响尽可能小.
除非我误解了您的方法,否则数据库中的一个结构更改可能会对应用程序的表面产生很大的影响区域.我看到这种关注点的分离使我和我的团队能够最大限度地减少这种情况.此外,团队中的任何新成员都应该更好地理解这种方法.
此外,您的方法似乎主张您的应用程序的业务逻辑驻留在您的数据库中?这对我来说是错误的,SQL非常擅长查询数据,而不是imho,表达业务逻辑.
虽然有趣的想法,虽然它感觉asp中的SQL只有一步之遥,这来自我糟糕的非结构化asp时代,让我感到恐惧.
一个原因 - 将您的域模型与数据库模型分开.
我所做的是使用测试驱动开发,所以我首先编写我的UI和模型层,并且模拟数据层,因此UI和模型是围绕特定于域的对象构建的,然后我将这些对象映射到我正在使用的技术数据层.让数据库结构决定应用程序的设计是个坏主意.在可能的情况下,首先编写应用程序,让它影响数据库的结构,而不是相反.
对我来说,归结为我不希望我的应用程序关注数据的存储方式.我可能会因为这样说而被打耳光...但你的应用程序不是你的数据,数据是应用程序的工件.我希望我的应用程序能够根据客户,订单和项目进行思考,而不是像DataSet,DataTables和DataRows这样的技术...因为谁知道这些技术会持续多久.
我同意总是存在一定量的耦合,但我更倾向于将耦合向上而不是向下.我可以更轻松地调整树的四肢和树叶,而不是改变它的树干.
我倾向于保留用于报告的sprocs,因为查询确实比应用程序通用数据访问有点麻烦.
我也倾向于认为在那个场景的早期适当的单元测试就像没有持久的一个列可能不是一个问题.
埃里克,你死了.对于任何真正可扩展/易于维护/强大的应用程序,唯一真正的答案是免除所有垃圾并坚持基础.
在我的职业生涯中,我遵循了类似的轨迹并得出了相同的结论.当然,我们被认为是异教徒,看起来很有趣.但我的东西运作良好.
应怀疑地看待每一行代码.
我想回答一个类似于你提议的例子.
在我的公司,我必须为产品构建一个简单的CRUD部分,我构建所有实体和一个单独的DAL.后来另一个开发人员不得不改变一个相关的表,他甚至重命名了几个字段.我必须更改以更新我的表单的唯一文件是该表的DAL.
(在我看来)实体带给项目的是:
Ortogonality:一层中的变化可能不会影响其他层(当然,如果您对数据库做出巨大更改,它会波及所有层,但大多数小变化都不会).
可测试性:您无需触摸数据库即可测试逻辑.这样可以提高测试的性能(允许您更频繁地运行它们).
关注点分离:在一个大产品中,您可以将数据库分配给DBA,他可以优化地狱.将模型分配给具有设计所需知识的业务专家.将个别表单分配给在webforms等方面更有经验的开发人员.
最后,我想补充一点,大多数ORM映射器都支持存储过程,因为这就是你所使用的.
干杯.
我认为你可能在这个话题上"咬得比你能咀嚼的多".当他称之为" 计算机科学越南 "时,泰德纽瓦德并不轻浮.
有一件事我可以绝对保证,它会改变任何人的观点,就像在无数其他博客,论坛,播客等上经常证明的那样.
对于一个有争议的话题进行公开的讨论和辩论当然是可以的,只是这一次已经做了很多次,以至于"双方"已经同意不同意并且只是继续编写软件.
如果你想进一步阅读双方,请参阅Ted博客上的文章,Ayende Rahein,Jimmy Nilson,Scott Bellware,Alt.Net,Stephen Forte,Eric Evans等.
@Dan,对不起,那不是我想要的那种东西.我知道这个理论.你的陈述"是一个非常糟糕的主意"并没有一个真实的例子支持.我们正在努力在更短的时间内开发软件,减少人员,减少错误,并且我们希望能够轻松地进行更改.根据我的经验,您的多层模型在所有上述类别中都是否定的.特别是关于使数据模型成为你做的最后一件事.从第1天开始,物理数据模型必须是一个重要的考虑因素.