|
|
1
59
我认为这取决于应用程序的“逻辑”有多复杂,以及你在哪里实现了它。如果你所有的逻辑都在存储过程中,而你的应用程序所做的只是调用这些过程并显示结果,那么开发实体对象确实是浪费时间。但是,对于对象之间有丰富交互的应用程序,而数据库只是一种持久性机制,拥有这些对象可能是有价值的。 所以,我想说,没有一个一刀切的答案。开发人员确实需要意识到,有时,过于OO可能会导致比解决更多的问题。 |
|
|
2
27
理论上说,高度内聚、松散耦合的实现是前进的方向。 所以我想你是在质疑这种方法,即分离关注点。 我的aspx.cs文件是否应该与数据库交互、调用存储过程并理解IDataReader? 在团队环境中,尤其是在处理应用程序的aspx部分的技术人员较少的情况下,我不需要这些人能够“接触”这些东西。 将我的域与数据库分离可以保护我免受数据库结构变化的影响,这当然是一件好事吗?当然,数据库的有效性是绝对重要的,所以让最擅长这方面的人在一个地方处理这些东西,尽可能少地影响系统的其他部分。 除非我误解了您的方法,否则数据库中的一个结构更改可能会对应用程序的表面产生很大的影响。我看到这种关注点的分离使我和我的团队能够最大限度地减少这种情况。此外,团队中的任何新成员都应该更好地理解这种方法。 此外,您的方法似乎主张应用程序的业务逻辑驻留在数据库中?这让我觉得不对,SQL非常擅长查询数据,而不是表达业务逻辑。 不过,这个想法很有趣,尽管它感觉离aspx中的SQL只有一步之遥,这让我充满了恐惧。 |
|
|
3
26
一个原因是将域模型与数据库模型分离。 我所做的是使用测试驱动开发,所以我首先编写UI和模型层,并模拟数据层,所以UI和模型是围绕特定领域的对象构建的,然后我将这些对象映射到我使用的数据层技术。让数据库结构决定应用程序的设计是个坏主意。在可能的情况下,先编写应用程序,让它影响数据库的结构,而不是相反。 |
|
|
4
21
对我来说,归根结底,我不希望我的应用程序关心数据的存储方式。我这么说可能会被打耳光。。。但您的应用程序不是您的数据,数据是应用程序的工件。我希望我的应用程序从客户、订单和项目的角度进行思考,而不是像DataSet、DataTables和DataRows这样的技术。。。因为谁知道这些会存在多久。 我同意总是有一定量的耦合,但我更喜欢这种耦合向上而不是向下。我调整树枝和树叶比改变树干更容易。 我倾向于保留存储过程用于报告,因为查询往往比应用程序的常规数据访问更糟糕。 我还倾向于认为,在这种场景的早期进行适当的单元测试,就像一列没有被持久化可能不是问题。 |
|
|
5
16
埃里克, 你已经死定了。对于任何真正可扩展/易于维护/健壮的应用程序,唯一真正的答案就是抛弃所有垃圾,坚持基本原则。 我的职业生涯也遵循了类似的轨迹,并得出了同样的结论。当然,我们被认为是异教徒,看起来很滑稽。但我的东西很好用。 每一行代码都应该受到怀疑。 |
|
|
6
10
我想举一个与你提出的例子相似的例子来回答。 在我的公司里,我必须为产品建立一个简单的CRUD部分,我建立了我所有的实体和一个单独的DAL。后来,另一位开发人员不得不更改一个相关的表,他甚至重命名了几个字段。为了更新表格,我唯一需要更改的文件是该表格的DAL。 (在我看来)实体给项目带来的是: 正交性:一个层中的更改可能不会影响其他层(当然,如果你对数据库进行巨大更改,它会波及所有层,但大多数小更改不会)。 可测试性:您可以在不接触数据库的情况下测试您的逻辑。这提高了测试的性能(使您能够更频繁地运行测试)。 关注点分离:在一个大产品中,你可以将数据库分配给DBA,他可以优化它。将模型分配给具有设计所需知识的业务专家。将单个表单分配给在web表单等方面更有经验的开发人员。。 最后,我想补充一点,大多数ORM映射程序都支持存储过程,因为这就是您正在使用的。 干杯 |
|
|
7
8
我认为你在这个话题上可能“咬文嚼字”。泰德·纽沃德称之为“ Vietnam of Computer Science ". 我可以绝对向你保证的一件事是,它不会改变任何人对此事的看法,正如在无数其他博客、论坛、播客等上经常证明的那样。 对一个有争议的话题进行公开的争论和辩论当然是可以的,只是这一次已经做了很多次,以至于双方都同意不同意,只是继续编写软件。 如果你想进一步阅读这两方面的内容,请参阅Ted博客上的文章,Ayende Rahein,Jimmy Nilson,Scott Bellware,Alt.Net,Stephen Forte,Eric Evans等。 |
|
|
8
7
@丹,对不起,那不是我要找的那种东西。我知道这个理论。你所说的“这是一个非常糟糕的想法”并没有一个真实的例子来支持。我们正在努力用更少的时间、更少的人、更少的错误开发软件,我们希望能够轻松地进行更改。根据我的经验,你的多层模型在上述所有类别中都是负面的。尤其是在将数据模型作为最后一件事时。从第一天起,物理数据模型就必须是一个重要的考虑因素。 |
|
|
9
4
我觉得你的问题很有趣。
|
|
|
10
4
实体对象可以促进在应用程序层上缓存。祝你缓存数据读取器好运。 |
|
|
11
4
我们还应该讨论实体到底是什么的概念。 当我阅读这篇讨论时,我得到的印象是,这里的大多数人都在从 Anemic Domain Model . 很多人都认为贫血域模型是一种反模式! 丰富的领域模型是有价值的。就是这样 Domain Driven Design 都是关于。 我个人认为OO是一种克服复杂性的方法。这不仅意味着技术复杂性(如数据访问、ui绑定、安全性…) 而且业务领域的复杂性 ! 如果我们能将OO技术应用于分析、建模、设计 并实施 我们的业务问题,这对于非琐碎应用程序的可维护性和可扩展性来说是一个巨大的优势! 实体和表之间存在差异。实体应该表示您的模型,表只是表示模型的数据方面! 诚然,数据的使用寿命比应用程序长,但请考虑 this quote 从…起 David Laribee :模特永远。。。数据是一个令人高兴的副作用。 有关此主题的更多链接: |
|
|
12
4
真有趣的问题。老实说,我无法证明为什么实体是好的。但我可以分享我喜欢它们的原因。代码类似
不关心顺序来自哪里-来自DB、来自web请求、来自单元测试等。它使该方法更明确地声明它到底需要什么,而不是采用DataRow并记录它希望具有哪些列以及它们应该是哪些类型。如果你以某种方式将其实现为存储过程,同样适用-你仍然需要将记录id推送到它,而它不必存在于DB中。 该方法的实现将基于Order抽象,而不是基于它在DB中的确切表示方式。我实现的大多数这样的操作实际上并不取决于如何存储这些数据。我确实知道,出于性能和可扩展性的目的,有些操作需要与DB结构耦合,只是根据我的经验,它们并不多。根据我的经验,只要知道Person有.getFirstName()返回String,.getAddress()返回Address,Address有.getZipCode()等就足够了,而且不在乎调用哪些表来存储这些数据。 如果你必须像你描述的那样处理这些问题,比如当额外的分栏报告性能时,那么对于你的任务来说,DB是一个关键部分,你确实应该尽可能地接近它。虽然实体可以提供一些方便的抽象,但它们也可以隐藏一些重要的细节。 可伸缩性是一个有趣的问题——大多数需要巨大可伸缩性的网站(如facebook、livejournal、flickr)倾向于使用DB禁欲主义方法,因为DB的使用尽可能少,可伸缩性问题通过缓存来解决,尤其是通过RAM的使用。 http://highscalability.com/ 有一些有趣的文章。 |
|
|
13
4
除了抽象和松散耦合之外,实体对象还有其他很好的理由。我最喜欢的一件事是用DataReader或DataTable无法获得的强类型。另一个原因是,如果做得好,适当的实体类可以通过对任何查看代码的人都可能理解的领域特定术语使用一级构造,而不是使用一堆带有字段名的字符串来索引DataRow,从而使代码更易于维护。存储过程实际上与ORM的使用正交,因为许多映射框架使您能够映射到存储过程。 我不认为sprocs+数据读取器可以替代好的ORM。对于存储过程,您仍然受到过程的类型签名的约束,并与之紧密耦合,该签名使用与调用代码不同的类型系统。可以对存储过程进行修改,以适应其他选项和架构更改。在模式发生更改的情况下,存储过程的另一种选择是使用视图——您可以将对象映射到视图,然后在更改视图时将其重新映射到基础表。 如果你的经验主要包括Java EE和CSLA,我可以理解你对ORM的厌恶。您可能想了解一下LINQ to SQL,这是一个非常轻量级的框架,主要是与数据库表的一对一映射,但通常只需要少量扩展即可使它们成为全面的业务对象。LINQ到SQL还可以将输入和输出对象映射到存储过程的参数和结果。 ADO。NET实体框架的另一个优点是,可以将数据库表视为相互继承的实体类,也可以将多个表中的列聚合为一个实体。如果需要更改模式,可以在不更改实际应用程序代码的情况下更改从概念模型到存储模式的映射。再说一遍,这里可以使用存储过程。 我认为,与应用程序的可扩展性问题相比,企业中更多的IT项目失败是因为代码无法维护或开发人员生产力低下(例如,存储过程编写和应用程序编写之间的上下文切换可能会导致这种情况)。 |
|
|
14
3
我还想补充一下 Dan's answer 将这两个模型分离可以使您的应用程序在不同的数据库服务器甚至数据库模型上运行。 |
|
|
15
3
如果您需要通过负载平衡多个web服务器来扩展应用程序,该怎么办?你可以在所有的网络服务器上安装完整的应用程序,但更好的解决方案是让网络服务器与应用程序服务器对话。 但如果没有任何实体对象,它们就没有太多可谈的了。 我并不是说,如果它是一个简单的、内部的、使用寿命短的应用程序,就不应该编写monolits。但是,一旦它变得适度复杂,或者应该持续相当长的时间,你真的需要考虑一个好的设计。 这样可以节省维护时间。 通过将应用程序逻辑与表示逻辑和数据访问分离,并在它们之间传递DTO,可以将它们解耦。允许他们独立改变。 |
|
|
16
3
你可能会发现 this comp.object上的帖子很有趣。 我并不声称同意或不同意,但这很有趣,(我认为)与这个话题有关。 |
|
|
17
3
一个问题: 如果您的所有业务逻辑都被困在数据库中,您如何处理断开连接的应用程序?
在我感兴趣的企业应用程序类型中,我们必须处理多个站点,其中一些站点必须能够在断开连接的状态下运行。
在数据库的存储过程中保留Domain层时,您必须坚持使用一种类型的应用程序,该应用程序需要对数据库有一个永久的视线。 它适用于特定类别的环境,但肯定不能覆盖整个范围 企业应用程序 . |
|
|
18
2
@jdecuyper,我经常对自己重复的一句格言是“如果你的业务逻辑不在你的数据库中,那只是一个建议”。我想保罗·尼尔森在他的一本书中说过。应用程序层和UI来来去去,但数据通常存在很长一段时间。 如何避免实体对象?主要是存储过程。我也坦率地承认,无论您是否打算,业务逻辑往往会渗透到应用程序的所有层。一定程度的耦合是固有的,也是不可避免的。 |
|
|
19
2
最近我一直在想同样的事情;有一段时间,我是CSLA的忠实用户,我喜欢说“你所有的商业逻辑(或者至少尽可能多地)都封装在商业实体中”这句话的纯粹性。 我已经看到,在数据库的设计与处理数据的方式不同的情况下,业务实体模型提供了很大的价值,这在许多业务软件中都是如此。 例如,“客户”的概念可能包括客户表中的主记录,以及客户下的所有订单,以及客户的所有员工及其联系信息,客户及其子代的一些属性可以从查找表中确定。从开发的角度来看,能够将客户作为一个单一的实体来工作真的很好,因为从业务的角度看,客户的概念包含了所有这些东西,这些关系可能会在数据库中强制执行,也可能不会强制执行。 虽然我很感激“如果你的业务规则不在你的数据库中,这只是一个建议”,但我也认为你不应该设计数据库来执行业务规则,你应该设计得高效、快速和规范。 也就是说,正如上面其他人所指出的,没有“完美的设计”,工具必须适合工作。但是,使用业务实体确实有助于维护和提高生产力,因为您知道去哪里修改业务逻辑,并且对象可以以直观的方式对真实世界的概念进行建模。 |
|
|
20
2
埃里克, 没有人会阻止你选择你想要的框架/方法。如果你要走“数据驱动/存储过程驱动”的道路,那么一定要去做!特别是如果它真的,真的能帮助你按时交付你的应用程序。 需要注意的是(问题的另一面是),您的所有业务规则都应该在存储过程上,而您的应用程序只不过是一个瘦客户端。 也就是说,若你们在OOP中进行应用程序,同样的规则也适用:保持一致。遵循OOP的原则,以及 那个 包括创建实体对象来表示域模型。 这里唯一真正的规则是单词 一致性 。没有人会阻止你以数据库为中心。没有人会阻止你做老式的结构化(又称功能性/程序性)程序。见鬼,没有人会阻止任何人执行COBOL风格的代码。但是,如果一个应用程序希望获得任何程度的成功,那么一旦走上这条路,它就必须非常、非常一致。 |
|
|
21
2
我真的不确定你认为“企业应用程序”是什么。但我得到的印象是,你将其定义为一个内部应用程序,其中RDBMS将是固定不变的,系统不必与任何其他系统(无论是内部还是外部)互操作。 但是,如果您有一个包含100个表的数据库,每个表相当于4个存储过程,仅用于基本的CRUD操作,即400个需要维护的存储过程,并且不是强类型的,因此很容易出现拼写错误,也不能进行单元测试,该怎么办。当你有了一个新的CTO,他是一个开源的传道者,并且想要将RDBMS从SQL Server更改为MySql时,会发生什么? 今天的许多软件,无论是企业应用程序还是产品,都在使用SOA,并且对公开Web服务有一些要求,至少我现在和曾经参与过的软件是这样做的。 使用您的方法,您最终会暴露一个或多个序列化的DataTable或DataRows。现在,如果客户得到保证,这可能被视为可以接受。NET和内部网络上。但是,当客户端未知时,您应该努力设计一个直观的API,在大多数情况下,您不想公开完整的数据库模式。 我当然不想向Java开发人员解释什么是DataTable以及如何使用它。还需要考虑Bandwith和有效负载大小以及序列化的DataTables,DataSet非常重。 软件设计没有灵丹妙药,这实际上取决于优先级,对我来说,它是在单元可测试代码和松散耦合的组件中,任何客户端都可以轻松使用。 就我的2美分 |
|
|
22
2
我想为OO和RDB之间的距离问题提供另一个角度:历史。 任何软件都有一个现实模型,在某种程度上是对现实的抽象。没有一个计算机程序能够捕捉到现实的所有复杂性,而编写程序只是为了从现实中解决一系列问题。因此,任何软件模型都是对现实的还原。有时软件模型会迫使现实自我简化。比如,当你想让汽车租赁公司为你预订任何一辆车,只要它是蓝色的,并且是合金的,但运营商不能遵守,因为你的请求不适合电脑。 RDB源于一种将信息放入表中的古老传统,称为会计。会计是在纸上完成的,然后是穿孔卡片,然后是在计算机上完成的。但会计已经是现实的还原。会计迫使人们长期遵循其制度,从而成为公认的现实。这就是为什么制作会计计算机软件相对容易的原因,早在计算机出现之前,会计就已经有了它的信息模型。 考虑到良好的会计系统的重要性,以及你从任何业务经理那里得到的认可,这些系统已经变得非常先进。数据库的基础现在非常稳固,没有人会犹豫是否要将重要数据保存在如此值得信赖的地方。 我想OO一定是在人们发现现实的其他方面比会计(已经是一种模型)更难建模的时候出现的。OO已经成为一个非常成功的想法,但OO数据的持久性相对不发达。RDB/Accounting取得了轻松的胜利,但OO是一个更大的领域(基本上是所有非会计的领域)。 我们中的许多人都想使用OO,但我们仍然希望数据的安全存储。还有什么比以与受人尊敬的会计系统相同的方式存储我们的数据更安全的呢?这是一个诱人的前景,但我们都会遇到同样的陷阱。与受益于会计传统和地位的RDB行业的巨大努力相比,很少有人费心考虑OO的持久性。 Prewayler和db4o是一些建议,我相信还有其他我没有听说过的,但似乎没有一个像冬眠一样得到一半的媒体关注。 对于多用户应用程序,尤其是web应用程序来说,将对象存储在好的旧文件中似乎并不被重视。 在我每天努力弥合OO和RDB之间的鸿沟时,我尽可能多地使用OO,但尽量将继承性降到最低。我不经常使用SP。我将只在看起来像会计的方面使用高级查询。 当裂缝永远关闭时,我会很高兴地吃晚饭。我认为当Oracle推出类似“Oracle对象实例库”的东西时,解决方案就会出现。要想真正流行起来,它必须有一个令人放心的名字。 |
|
|
23
1
现在时间不多,但我只是一时兴起。。。 实体模型可以为数据库(和其他可能的系统)提供一个一致的接口,甚至超出了存储过程接口的功能。通过使用企业范围的业务模型,您可以确保所有应用程序都能一致地影响数据,这是一件非常重要的事情。否则,你最终会得到糟糕的数据,这简直是邪恶的。 如果你只有一个应用程序,那么你就没有真正的“企业”系统,无论这个应用程序或你的数据有多大。在这种情况下,你可以使用类似于你所谈论的方法。如果您决定在未来发展您的系统,请注意所需的工作。 以下是一些你应该记住的事情(IMO):
|
|
|
24
1
有时,您的应用程序和数据层并没有紧密耦合。例如,您可能有一个电话计费应用程序。稍后,您可以创建一个单独的应用程序来监控手机使用情况,以便a)更好地向您做广告b)优化您的手机计划。 这些应用程序有不同的关注点和数据需求(即使数据来自同一个数据库),它们也会驱动不同的设计。如果让数据库驱动代码,代码库最终可能会变得一团糟(在任何一个应用程序中),并成为维护的噩梦。 |
|
|
25
1
具有与数据存储逻辑分离的域逻辑的应用程序适用于任何类型的数据源(数据库或其他)或UI(web或windows(或linux等))应用程序。 你的数据库几乎被卡住了,如果你所在的公司对你使用的当前数据库系统感到满意,这还不错。然而,由于数据库会随着时间的推移而发展,您的公司可能会想要使用一个非常整洁的新数据库系统。如果他们想切换到web服务的数据访问方法(就像面向服务的体系结构有时会做的那样),该怎么办。您可能需要将存储过程移植到各处。 此外,域逻辑还抽象了UI,这在具有不断发展的UI的大型复杂系统中可能更为重要(尤其是当它们不断寻找更多客户时)。 此外,尽管我同意存储过程与域逻辑的问题没有明确的答案。我属于领域逻辑阵营(我认为随着时间的推移,他们正在获胜),因为我相信精心设计的存储过程比精心设计的领域逻辑更难维护。但这是另一场辩论 |
|
|
26
0
我认为你只是习惯于编写一种特定的应用程序,并解决某种问题。您似乎是从“数据库优先”的角度对此进行攻击。有很多开发人员将数据持久化到数据库中,但性能并不是首要任务。在许多情况下,在持久性层上进行抽象可以极大地简化代码,而且性能成本也不是问题。 无论你在做什么,都不是OOP。这并没有错,只是不是OOP,把你的解决方案应用于其他所有问题是没有意义的。 |
|
|
27
0
有趣的问题。有几个想法:
|
|
|
28
0
好问题! 我比较喜欢的一种方法是创建一个迭代器/生成器对象,该对象发出与特定上下文相关的对象实例。通常,这个对象封装了一些底层的数据库访问内容,但在使用它时我不需要知道。 例如
我发现,当我有一个巨大的数据集要处理时,这种方法效果很好,如果做得好,它会给我提供相对容易测试的小型瞬态对象。 它基本上是数据库访问的一层薄薄的东西,但它仍然给了我在需要时抽象它的灵活性。 |
|
|
29
0
我的应用程序中的对象往往与数据库一一相关,但我发现使用Linq to Sql而不是sprocs可以更容易地编写复杂的查询,尤其是能够使用延迟执行来构建查询。例如来自图像中的r。使用者评级等。这节省了我在sql中计算几个联接语句的时间,并使Skip&Take for pageing还简化了代码,而不必嵌入row_number&'over'代码。 |
|
|
30
0
为什么要停留在实体对象上?如果你在企业级应用程序中看不到实体对象的价值,那么只需用纯函数/过程语言进行数据访问,并将其连接到UI。为什么不去掉所有OO的“绒毛”呢? |
|
|
Johnny T · 基于当前值的SQL合并表[重复] 1 年前 |
|
John D · 需要为NULL或NOT NULL的WHERE子句 1 年前 |
|
ojek · 如何对SQL结果进行分组和编号? 1 年前 |
|
|
senek · 如何在PL/SQL中将选择结果(列)放入数组中 1 年前 |
|
|
Sax · 规范化Google表格(第一步) 1 年前 |
|
|
Jatin · 检索卷计数的动态sql抛出错误语法错误[关闭] 1 年前 |
|
|
Andrus · 如何在sql中查找第二个匹配项 1 年前 |