I really need to see some honest, thoughtful debate on the merits of the currently accepted enterprise application design paradigm.
我真的需要看到关于当前被接受的企业应用程序设计范例的优点的一些诚实的、深思熟虑的辩论。
I am not convinced that entity objects should exist.
我不相信实体对象应该存在。
By entity objects I mean the typical things we tend to build for our applications, like "Person", "Account", "Order", etc.
所谓实体对象,我指的是我们为应用程序构建的典型对象,比如“Person”、“Account”、“Order”等等。
My current design philosophy is this:
我目前的设计理念是:
- All database access must be accomplished via stored procedures.
- 所有数据库访问必须通过存储过程完成。
- Whenever you need data, call a stored procedure and iterate over a SqlDataReader or the rows in a DataTable
- 每当需要数据时,调用存储过程并在SqlDataReader或DataTable中的行上进行迭代
(Note: I have also built enterprise applications with Java EE, java folks please substitute the equvalent for my .NET examples)
(注意:我还用Java EE构建了企业应用程序,Java用户请用等价代替我的。net示例)
I am not anti-OO. I write lots of classes for different purposes, just not entities. I will admit that a large portion of the classes I write are static helper classes.
我不是anti-OO。我为不同的目的而编写了很多类,只是没有实体。我承认我编写的类中有很大一部分是静态助手类。
I am not building toys. I'm talking about large, high volume transactional applications deployed across multiple machines. Web applications, windows services, web services, b2b interaction, you name it.
我不是在造玩具。我说的是跨多台机器部署的大容量事务应用程序。Web应用程序、windows服务、Web服务、b2b交互,您可以命名它。
I have used OR Mappers. I have written a few. I have used the Java EE stack, CSLA, and a few other equivalents. I have not only used them but actively developed and maintained these applications in production environments.
我用过或用过地图。我已经写了一些。我使用了Java EE堆栈、CSLA和其他一些类似的东西。我不仅使用了它们,而且在生产环境中积极开发和维护这些应用程序。
I have come to the battle-tested conclusion that entity objects are getting in our way, and our lives would be so much easier without them.
我得出了一个久经考验的结论:实体对象正在阻碍我们,如果没有它们,我们的生活将会容易得多。
Consider this simple example: you get a support call about a certain page in your application that is not working correctly, maybe one of the fields is not being persisted like it should be. With my model, the developer assigned to find the problem opens exactly 3 files. An ASPX, an ASPX.CS and a SQL file with the stored procedure. The problem, which might be a missing parameter to the stored procedure call, takes minutes to solve. But with any entity model, you will invariably fire up the debugger, start stepping through code, and you may end up with 15-20 files open in Visual Studio. By the time you step down to the bottom of the stack, you forgot where you started. We can only keep so many things in our heads at one time. Software is incredibly complex without adding any unnecessary layers.
考虑一下这个简单的例子:您在应用程序中获得了一个关于某个页面的支持调用,该页面不能正常工作,可能其中的一个字段不能像它应该那样被持久化。在我的模型中,开发人员被分配去发现这个问题恰好打开了3个文件。一个ASPX、一个ASPX。CS和带有存储过程的SQL文件。这个问题可能是存储过程调用中丢失的一个参数,需要几分钟才能解决。但是对于任何实体模型,您都必须启动调试器,开始执行代码,并且您可能最终在Visual Studio中打开15-20个文件。当您走到堆栈的底部时,您就会忘记从哪里开始了。我们一次只能记住这么多东西。软件非常复杂,没有添加任何不必要的层。
Development complexity and troubleshooting are just one side of my gripe.
开发复杂性和故障排除只是我抱怨的一方面。
Now let's talk about scalability.
现在我们来谈谈可扩展性。
Do developers realize that each and every time they write or modify any code that interacts with the database, they need to do a throrough analysis of the exact impact on the database? And not just the development copy, I mean a mimic of production, so you can see that the additional column you now require for your object just invalidated the current query plan and a report that was running in 1 second will now take 2 minutes, just because you added a single column to the select list? And it turns out that the index you now require is so big that the DBA is going to have to modify the physical layout of your files?
开发人员是否意识到,每当他们编写或修改与数据库交互的任何代码时,他们都需要对数据库的确切影响进行大量分析?不仅发展复制,我的意思是一个模仿生产,所以你可以看到,你现在需要的附加列你的对象失效报告当前的查询计划和运行在1秒将花2分钟,仅仅因为你单个列添加到选择列表吗?您现在需要的索引太大了,以至于DBA需要修改文件的物理布局?
If you let people get too far away from the physical data store with an abstraction, they will create havoc with an application that needs to scale.
如果您让人们使用抽象远离物理数据存储,他们将对需要扩展的应用程序造成严重破坏。
I am not a zealot. I can be convinced if I am wrong, and maybe I am, since there is such a strong push towards Linq to Sql, ADO.NET EF, Hibernate, Java EE, etc. Please think through your responses, if I am missing something I really want to know what it is, and why I should change my thinking.
我不是*分子。如果我是错的,我可以相信,也许我是错的,因为对于Linq到Sql来说,ADO是如此的强大。NET EF, Hibernate, Java EE等,请仔细考虑你的回复,如果我漏掉了什么,我真的想知道是什么,为什么要改变我的想法。
[Edit]
(编辑)
It looks like this question is suddenly active again, so now that we have the new comment feature I have commented directly on several answers. Thanks for the replies, I think this is a healthy discussion.
看起来这个问题突然又活跃起来了,现在我们有了新的评论特性,我已经直接评论了几个答案。谢谢你的回复,我认为这是一个健康的讨论。
I probably should have been more clear that I am talking about enterprise applications. I really can't comment on, say, a game that's running on someone's desktop, or a mobile app.
我可能应该更清楚地说,我在谈论企业应用程序。我真的不能评论,比如说,一个在某人的桌面上运行的游戏,或者一个移动应用。
One thing I have to put up here at the top in response to several similar answers: orthogonality and separation of concerns often get cited as reasons to go entity/ORM. Stored procedures, to me, are the best example of separation of concerns that I can think of. If you disallow all other access to the database, other than via stored procedures, you could in theory redesign your entire data model and not break any code, so long as you maintained the inputs and outputs of the stored procedures. They are a perfect example of programming by contract (just so long as you avoid "select *" and document the result sets).
有一件事我必须放在这里作为对几个相似答案的回应:正交性和关注点的分离经常被引用作为去实体/ORM的理由。对我来说,存储过程是分离关注点的最好例子。如果不允许通过存储过程访问数据库,那么理论上可以重新设计整个数据模型,并且只要维护存储过程的输入和输出,就不会破坏任何代码。它们是契约式编程的完美示例(只要您避免“select *”并记录结果集)。
Ask someone who's been in the industry for a long time and has worked with long-lived applications: how many application and UI layers have come and gone while a database has lived on? How hard is it to tune and refactor a database when there are 4 or 5 different persistence layers generating SQL to get at the data? You can't change anything! ORMs or any code that generates SQL lock your database in stone.
问一个在这个行业中工作了很长时间并且使用了很长时间的应用程序的人:当一个数据库存在时,有多少应用程序和UI层来来去去?当有4到5个不同的持久性层生成SQL以获取数据时,调整和重构数据库有多难呢?你不能改变任何东西!orm或任何生成SQL锁定数据库的代码。
41 个解决方案
#1
59
I think it comes down to how complicated the "logic" of the application is, and where you have implemented it. If all your logic is in stored procedures, and all your application does is call those procedures and display the results, then developing entity objects is indeed a waste of time. But for an application where the objects have rich interactions with one another, and the database is just a persistence mechanism, there can be value to having those objects.
我认为这取决于应用程序的“逻辑”有多复杂,以及在哪里实现了它。如果所有的逻辑都在存储过程中,而应用程序所做的就是调用这些过程并显示结果,那么开发实体对象确实是浪费时间。但是对于一个对象之间具有丰富交互的应用程序,并且数据库只是一个持久性机制,拥有这些对象是有价值的。
So, I'd say there is no one-size-fits-all answer. Developers do need to be aware that, sometimes, trying to be too OO can cause more problems than it solves.
所以,我想说,没有一种方法适合所有人。开发人员确实需要意识到,有时候太过OO会导致比它解决的问题更多的问题。
#2
27
Theory says that highly cohesive, loosely coupled implementations are the way forward.
理论认为,高度内聚、松散耦合的实现是前进的方向。
So I suppose you are questioning that approach, namely separating concerns.
所以我想你是在质疑这种方法,即分离关注点。
Should my aspx.cs file be interacting with the database, calling a sproc, and understanding IDataReader?
应该我的aspx。cs文件正在与数据库交互,调用sproc,并理解IDataReader?
In a team environment, especially where you have less technical people dealing with the aspx portion of the application, I don't need these people being able to "touch" this stuff.
在团队环境中,特别是当你的技术人员很少处理应用程序的aspx部分时,我不需要这些人能够“触摸”这些东西。
Separating my domain from my database protects me from structural changes in the database, surely a good thing? Sure database efficacy is absolutely important, so let someone who is most excellent at that stuff deal with that stuff, in one place, with as little impact on the rest of the system as possible.
将域从数据库中分离出来可以保护我不受数据库中结构变化的影响,这肯定是件好事吗?当然,数据库的有效性是绝对重要的,所以让那些最擅长数据库的人在一个地方处理这些东西,对系统其他部分的影响尽可能小。
Unless I am misunderstanding your approach, one structural change in the database could have a large impact area with the surface of your application. I see that this separation of concerns enables me and my team to minimise this. Also any new member of the team should understand this approach better.
除非我误解了您的方法,否则数据库中的一个结构更改可能会对应用程序的表面产生很大的影响。我看到这种分离的关注点使我和我的团队能够将这一点最小化。团队中的任何新成员都应该更好地理解这种方法。
Also, your approach seems to advocate the business logic of your application to reside in your database? This feels wrong to me, SQL is really good at querying data, and not, imho, expressing business logic.
而且,您的方法似乎支持应用程序的业务逻辑驻留在数据库中?在我看来,这是不对的,SQL确实擅长查询数据,而不是表达业务逻辑。
Interesting thought though, although it feels one step away from SQL in the aspx, which from my bad old unstructured asp days, fills me with dread.
然而,有趣的想法是,尽管在aspx中,它感觉离SQL只有一步之遥,而在我以前糟糕的非结构化asp时代,SQL使我充满了恐惧。
#3
25
One reason - separating your domain model from your database model.
一个原因是将域模型与数据库模型分离。
What I do is use Test Driven Development so I write my UI and Model layers first and the Data layer is mocked, so the UI and model is build around domain specific objects, then later I map these objects to what ever technology I'm using the the Data Layer. Its a bad idea to let the database structure determine the design of your application. Where possible write the app first and let that influence the structure of your database, not the other way around.
我所做的是使用测试驱动开发,我首先编写UI和模型层,然后对数据层进行模拟,因此UI和模型是围绕领域特定对象构建的,然后我将这些对象映射到我使用数据层的任何技术。让数据库结构决定应用程序的设计不是一个好主意。如果可能的话,首先编写应用程序,让它影响数据库的结构,而不是反过来。
#4
22
For me it boils down to I don't want my application to be concerned with how the data is stored. I'll probably get slapped for saying this...but your application is not your data, data is an artifact of the application. I want my application to be thinking in terms of Customers, Orders and Items, not a technology like DataSets, DataTables and DataRows...cuz who knows how long those will be around.
对我来说,它归结为我不希望我的应用程序关心数据是如何存储的。我可能会因为这样说而被打上耳光……但是您的应用程序不是您的数据,数据是应用程序的工件。我希望我的应用程序考虑的是客户、订单和项目,而不是数据集、DataTables和DataRows等技术。因为谁知道它们会存在多久。
I agree that there is always a certain amount of coupling, but I prefer that coupling to reach upwards rather than downwards. I can tweak the limbs and leaves of a tree easier than I can alter it's trunk.
我同意总有一定数量的耦合,但我宁愿耦合向上而不是向下。我可以更容易地调整树的四肢和叶子,而不是我可以改变它的树干。
I tend to reserve sprocs for reporting as the queries do tend to get a little nastier than the applications general data access.
我倾向于保留sprocs用于报告,因为查询比应用程序一般的数据访问更糟糕。
I also tend to think with proper unit testing early on that scenario's like that one column not being persisted is likely not to be a problem.
我也倾向于认为,在这个场景的早期进行适当的单元测试,就像没有持久化的一列很可能不是问题。
#5
16
Eric, You are dead on. For any really scalable / easily maintained / robust application the only real answer is to dispense with all the garbage and stick to the basics.
埃里克,你死定了。对于任何真正可伸缩/容易维护/健壮的应用程序来说,唯一真正的答案是不使用所有的垃圾并坚持基本原则。
I've followed a similiar trajectory with my career and have come to the same conclusions. Of course, we're considered heretics and looked at funny. But my stuff works and works well.
在我的职业生涯中,我遵循着相似的轨迹,并得出了相同的结论。当然,我们被认为是异端,而且看起来很有趣。但是我的东西很好用。
Every line of code should be looked at with suspicion.
每一行代码都应该被怀疑。
#6
11
I would like to answer with an example similar to the one you proposed.
我想用一个类似于你提出的例子来回答。
On my company I had to build a simple CRUD section for products, I build all my entities and a separate DAL. Later another developer had to change a related table and he even renamed several fields. The only file I had to change to update my form was the DAL for that table.
在我的公司,我必须为产品构建一个简单的CRUD部分,我构建所有实体和一个单独的DAL。后来,另一个开发人员不得不更改一个相关的表,他甚至重新命名了几个字段。为了更新表单,我必须更改的唯一文件是该表的DAL。
What (in my opinion) entities brings to a project is:
(在我看来)实体给项目带来的是:
Ortogonality: Changes in one layer might not affect other layers (off course if you make a huge change on the database it would ripple through all the layers but most small changes won't).
Ortogonality:一个层中的更改可能不会影响其他层(当然,如果您对数据库做了巨大的更改,那么它将影响所有层,但大多数小更改不会)。
Testability: You can test your logic with out touching your database. This increases performance on your tests (allowing you to run them more frequently).
可测试性:您可以在不接触数据库的情况下测试逻辑。这提高了测试的性能(允许您更频繁地运行它们)。
Separation of concerns: In a big product you can assign the database to a DBA and he can optimize the hell out of it. Assign the Model to a business expert that has the knowledge necessary to design it. Assign individual forms to developers more experienced on webforms etc..
关注点分离:在大型产品中,您可以将数据库分配给DBA, DBA可以从中进行优化。将模型分配给具有设计模型所需知识的业务专家。将个人表单分配给在web表单等方面更有经验的开发人员。
Finally I would like to add that most ORM mappers support stored procedures since that's what you are using.
最后,我想补充一点,大多数ORM映射器都支持存储过程,因为这正是您所使用的。
Cheers.
欢呼。
#7
8
I think you may be "biting off more than you can chew" on this topic. Ted Neward was not being flippant when he called it the "Vietnam of Computer Science".
我认为你可能在这个话题上“贪多嚼不烂”。Ted Neward称其为“计算机科学的越南”时并不轻率。
One thing I can absolutely guarantee you is that it will change nobody's point of view on the matter, as has been proven so often on innumerable other blogs, forums, podcasts etc.
有一件事我可以向你保证,那就是它不会改变任何人对这件事的看法,就像在无数其他博客、论坛、播客上经常被证明的那样。
It's certainly ok to have open disucssion and debate about a controversial topic, it's just this one has been done so many times that both "sides" have agreed to disagree and just got on with writing software.
对一个有争议的话题进行公开的离题和辩论当然是可以的,只是这个话题已经被做了很多次了,以至于双方都同意不同意,只是继续写软件。
If you want to do some further reading on both sides, see articles on Ted's blog, Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans etc.
如果你想在双方都做进一步的阅读,请参阅Ted的博客,Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans等。
#8
7
@Dan, sorry, that's not the kind of thing I'm looking for. I know the theory. Your statement "is a very bad idea" is not backed up by a real example. We are trying to develop software in less time, with less people, with less mistakes, and we want the ability to easily make changes. Your multi-layer model, in my experience, is a negative in all of the above categories. Especially with regards to making the data model the last thing you do. The physical data model must be an important consideration from day 1.
@Dan,对不起,那不是我要找的东西。我知道这个理论。你所说的“是一个非常糟糕的想法”没有一个真实的例子来支持。我们正试图用更少的时间、更少的人员、更少的错误来开发软件,我们希望能够轻松地进行更改。根据我的经验,你的多层模型在以上所有类别中都是负面的。尤其是关于将数据模型作为最后一件事。从第一天开始,物理数据模型就必须是一个重要的考虑因素。
#9
4
I found your question really interesting.
Usually I need entities objects to encapsulate the business logic of an application. It would be really complicated and inadequate to push this logic into the data layer.
What would you do to avoid these entities objects? What solution do you have in mind?
我发现你的问题很有趣。通常,我需要实体对象来封装应用程序的业务逻辑。将这种逻辑推入数据层会非常复杂和不充分。如何避免这些实体对象?你有什么解决办法吗?
#10
4
Entity Objects can facilitate cacheing on the application layer. Good luck caching a datareader.
实体对象可以促进应用程序层上的缓存。好运气缓存一个datareader。
#11
4
We should also talk about the notion what entities really are. When I read through this discussion, I get the impression that most people here are looking at entities in the sense of an Anemic Domain Model. A lot of people are considering the Anemic Domain Model as an antipattern!
我们还应该讨论实体的概念。当我通读这篇讨论时,我得到的印象是,这里的大多数人都是从贫血的领域模型的角度来看待实体的。许多人认为贫血域模型是一种反模式!
There is value in rich domain models. That is what Domain Driven Design is all about. I personally believe that OO is a way to conquer complexity. This means not only technical complexity (like data-access, ui-binding, security ...) but also complexity in the business domain!
在丰富的领域模型中有价值。这就是领域驱动设计的意义所在。我个人认为OO是一种克服复杂性的方法。这不仅意味着技术复杂性(如数据访问、ui绑定、安全性……),还意味着业务领域的复杂性!
If we can apply OO techniques to analyze, model, design and implement our business problems, this is a tremendous advantage for maintainability and extensibility of non-trivial applications!
如果我们能够应用OO技术来分析、建模、设计和实现我们的业务问题,这对于非平凡应用程序的可维护性和可扩展性来说是一个巨大的优势!
There are differences between your entities and your tables. Entities should represent your model, tables just represent the data-aspect of your model!
实体和表之间存在差异。实体应该代表您的模型,表仅仅代表模型的数据方面!
It is true that data lives longer than apps, but consider this quote from David Laribee: Models are forever ... data is a happy side effect.
数据确实比应用程序寿命长,但想想大卫·拉里比(David Laribee)的话:模型是永恒的……数据是一个好的副作用。
Some more links on this topic:
更多关于这个话题的链接:
-
Why Setters and Getters are evil
为什么定居者和getter都是邪恶的
-
返回纯OO
-
POJO和NOJO
-
超级模型第2部分
-
TDD、模拟和设计
#12
4
Really interesting question. Honestly I can not prove why entities are good. But I can share my opinion why I like them. Code like
很有趣的问题。老实说,我无法证明为什么实体是好的。但是我可以分享我喜欢它们的原因。代码
void exportOrder(Order order, String fileName){...};
is not concerned where order came from - from DB, from web request, from unit test, etc. It makes this method more explicitly declare what exactly it requires, instead of taking DataRow and documenting which columns it expects to have and which types they should be. Same applies if you implement it somehow as stored procedure - you still need to push record id to it, while it not necessary should be present in DB.
不关心顺序来自哪里——来自DB、web请求、单元测试等等。它使这个方法更明确地声明它所需要的内容,而不是使用DataRow并记录它希望拥有的列以及它们应该是什么类型。同样,如果您以某种方式实现它作为存储过程——您仍然需要将记录id推到它,而不需要在DB中存在。
Implementation of this method would be done based on Order abstraction, not based on how exactly it is presented in DB. Most of such operations which I implemented really do not depend on how this data is stored. I do understand that some operations require coupling with DB structure for perfomance and scalability purposes, just in my experience there are not too much of them. In my experience very often it is enough to know that Person has .getFirstName() returning String, and .getAddress() returning Address, and address has .getZipCode(), etc - and do not care which tables are involed to store that data.
该方法的实现将基于订单抽象,而不是基于如何在DB中显示它。我实现的大多数此类操作实际上并不依赖于如何存储这些数据。我确实理解,出于性能和可扩展性的目的,有些操作需要与DB结构耦合,根据我的经验,这些操作并不多。在我的经验中,通常只要知道这个人有. getfirstname()返回字符串,. getaddress()返回地址,地址有. getzipcode()等,就足够了,而且不需要关心要使用哪些表来存储该数据。
If you have to deal with such problems as you described, like when additional column breaks report perfomance, then for your tasks DB is a critical part, and you indeed should be as close as possible to it. While entities can provide some convenient abstractions they can hide some important details as well.
如果您必须处理您所描述的这些问题,比如当附加的列中断报表执行时,那么对于您的任务DB是一个关键部分,您确实应该尽可能地接近它。虽然实体可以提供一些方便的抽象,但是它们也可以隐藏一些重要的细节。
Scalability is interesting point here - most of websites which require enormous scalability (like facebook, livejournal, flickr) tend to use DB-ascetic approach, when DB is used as rare as possible and scalability issues are solved by caching, especially by RAM usage. http://highscalability.com/ has some interesting articles on it.
可扩展性在这里是很有趣的一点——大多数需要大量可扩展性的网站(如facebook、livejournal、flickr)都倾向于使用DB-ascetic方法,当DB尽可能少地使用时,可扩展性问题通过缓存(特别是RAM的使用)来解决。http://highscalability.com/有一些有趣的文章。
#13
4
There are other good reasons for entity objects besides abstraction and loose coupling. One of the things I like most is the strong typing that you can't get with a DataReader or a DataTable. Another reason is that when done well, proper entity classes can make the code more maintanable by using first-class constructs for domain-specific terms that anyone looking at the code is likely to understand rather than a bunch of strings with field names in them used for indexing a DataRow. Stored procedures are really orthogonal to the use of an ORM since a lot of mapping frameworks give you the ability to map to sprocs.
除了抽象和松耦合之外,实体对象还有其他好的原因。我最喜欢的一件事是,你无法使用DataReader或DataTable的强类型。另一个原因是,如果做得很好,适当的实体类可以通过为特定于域的术语使用一流的构造来使代码更易于维护,任何查看代码的人都可能理解这些术语,而不是使用字段名作为索引的字符串。存储过程与ORM的使用是正交的,因为许多映射框架都允许您映射到sprocs。
I wouldn't consider sprocs + datareaders a substitute for a good ORM. With stored procedures, you're still constrained by, and tightly-coupled to, the procedure's type signature, which uses a different type system than the calling code. Stored procedures can be subject to modification to acommodate additional options and schema changes. An alternative to stored procedures in the case where the schema is subject to change is to use views--you can map objects to views and then re-map views to the underlying tables when you change them.
我不认为sprocs + datareaders是一个好的ORM的替代品。对于存储过程,您仍然受到过程的类型签名的限制,并与之紧密耦合,该签名使用与调用代码不同的类型系统。存储过程可以修改为acommodate附加选项和模式更改。在模式可能发生更改的情况下,存储过程的另一种替代方法是使用视图——您可以将对象映射到视图,然后在更改视图时将视图重新映射到底层表。
I can understand your aversion to ORMs if your experience mainly consists of Java EE and CSLA. You might want to have a look at LINQ to SQL, which is a very lightweight framework and is primarily a one-to-one mapping with the database tables but usually only needs minor extension for them to be full-blown business objects. LINQ to SQL can also map input and output objects to stored procedures' paramaters and results.
如果您的经验主要是Java EE和CSLA,我可以理解您对orm的反感。您可能想了解一下LINQ到SQL,这是一个非常轻量级的框架,主要是与数据库表的一对一映射,但通常只需要对它们进行很小的扩展,就可以使它们成为成熟的业务对象。LINQ to SQL还可以将输入和输出对象映射到存储过程的参数和结果。
The ADO.NET Entity framework has the added advantage that your database tables can be viewed as entity classes inheriting from each other, or as columns from multiple tables aggregated into a single entity. If you need to change the schema, you can change the mapping from the conceptual model to the storage schema without changing the actual application code. And again, stored procedures can be used here.
ADO。NET实体框架还有一个额外的优点,即可以将数据库表视为相互继承的实体类,或者将多个表的列聚合为一个实体。如果需要更改模式,可以将映射从概念模型更改为存储模式,而无需更改实际的应用程序代码。同样,存储过程也可以在这里使用。
I think that more IT projects in enterprises fail because of unmaintainability of the code or poor developer productivity (which can happen from, e.g., context switching between sproc-writing and app-writing) than scalability problems of an application.
我认为,与应用程序的可伸缩性问题相比,企业中的IT项目失败的更多原因是代码的不可维护性或开发人员的生产力低下(这可能发生在sproc编写和应用程序编写之间的上下文切换)。
#14
3
I would also like to add to Dan's answer that separating both models could enable your application to be run on different database servers or even database models.
我还想补充Dan的答案,即分离这两个模型可以使您的应用程序在不同的数据库服务器上运行,甚至可以在数据库模型上运行。
#15
3
What if you need to scale your app by load balancing more than one web server? You could install the full app on all web servers, but a better solution is to have the web servers talk to an application server.
如果需要通过加载多个web服务器来平衡应用程序,该怎么办?您可以在所有web服务器上安装完整的应用程序,但是更好的解决方案是让web服务器与应用服务器对话。
But if there aren't any entity objects, they won't have very much to talk about.
但是如果没有任何实体对象,它们就不会有太多要讨论的内容。
I'm not saying that you shouldn't write monoliths if its a simple, internal, short life application. But as soon as it gets moderately complex, or it should last a significant amount of time, you really need to think about a good design.
我并不是说,如果这是一个简单的、内部的、短寿命的应用程序,你就不应该写“巨石”。但是一旦它变得适度复杂,或者它应该持续很长一段时间,你就需要考虑一个好的设计。
This saves time when it comes to maintaining it.
这节省了维护的时间。
By splitting application logic from presentation logic and data access, and by passing DTOs between them, you decouple them. Allowing them to change independently.
通过将应用程序逻辑从表示逻辑和数据访问中分离出来,并在它们之间传递dto,可以对它们进行解耦。允许他们独立地改变。
#16
3
You might find this post on comp.object interesting.
你可能会在com .object上发现这篇文章很有趣。
I'm not claiming to agree or disagree but it's interesting and (I think) relevant to this topic.
我并不是说我同意或不同意,但它很有趣并且(我认为)与这个话题相关。
#17
3
A question: How do you handle disconnected applications if all your business logic is trapped in the database?
问题:如果所有业务逻辑都被困在数据库中,您如何处理断开连接的应用程序?
In the type of Enterprise application I'm interested in, we have to deal with multiple sites, some of them must be able to function in a disconnected state.
If your business logic is encapsulated in a Domain layer that is simple to incorporate into various application types -say, as a dll
- then I can build applications that are aware of the business rules and are able, when necessary, to apply them locally.
在我感兴趣的企业应用程序类型中,我们必须处理多个站点,其中一些站点必须能够在断开连接的状态下运行。如果您的业务逻辑封装在一个域层中,这个域层可以简单地合并到各种应用程序类型中(例如,作为一个dll),那么我就可以构建知道业务规则的应用程序,并在必要时能够在本地应用它们。
In keeping the Domain layer in stored procedures on the database you have to stick with a single type of application that needs a permanent line-of-sight to the database.
为了在数据库的存储过程中保持域层,您必须使用一种类型的应用程序,这种应用程序需要数据库的永久视线。
It's ok for a certain class of environments, but it certainly doesn't cover the whole spectrum of Enterprise applications.
对于特定类型的环境来说,这是可以接受的,但它肯定不包括企业应用程序的整个范围。
#18
2
@jdecuyper, one maxim I repeat to myself often is "if your business logic is not in your database, it is only a recommendation". I think Paul Nielson said that in one of his books. Application layers and UI come and go, but data usually lives for a very long time.
@jdecuyper,我经常对自己说的一句话是“如果你的业务逻辑不在你的数据库中,那它只是一个建议”。我认为保罗·尼尔森在他的一本书中说过。应用程序层和UI来来去去,但数据通常会存在很长一段时间。
How do I avoid entity objects? Stored procedures mostly. I also freely admit that business logic tends to reach through all layers in an application whether you intend it to or not. A certain amount of coupling is inherent and unavoidable.
如何避免实体对象?主要是存储过程。我还坦率地承认,无论您是否有意,业务逻辑都倾向于贯穿应用程序的所有层。一定数量的耦合是不可避免的。
#19
2
I have been thinking about this same thing a lot lately; I was a heavy user of CSLA for a while, and I love the purity of saying that "all of your business logic (or at least as much as is reasonably possible) is encapsulated in business entities".
我最近一直在思考同样的事情;有一段时间,我一直是CSLA的忠实用户,我喜欢这种纯粹的说法:“您的所有业务逻辑(或至少尽可能多地)都封装在业务实体中”。
I have seen the business entity model provide a lot of value in cases where the design of the database is different than the way you work with the data, which is the case in a lot of business software.
我已经看到,在数据库的设计与处理数据的方式不同的情况下,业务实体模型提供了大量的价值,这在很多业务软件中都是如此。
For example, the idea of a "customer" may consist of a main record in a Customer table, combined with all of the orders the customer has placed, as well as all the customer's employees and their contact information, and some of the properties of a customer and its children may be determined from lookup tables. It's really nice from a development standpoint to be able to work with the Customer as a single entity, since from a business perspective, the concept of Customer contains all of these things, and the relationships may or may not be enforced in the database.
例如,“客户”的概念可能由一个主要记录客户表,结合所有的客户订单,以及所有客户的员工和他们的联系信息,和一些客户的性质和它的孩子可以从查找表来确定。从开发的角度来看,能够将客户作为一个单独的实体来工作是非常好的,因为从业务的角度来看,客户的概念包含了所有这些东西,并且关系在数据库中可能被执行,也可能不被执行。
While I appreciate the quote that "if your business rule is not in your database, it's only a suggestion", I also believe that you shouldn't design the database to enforce business rules, you should design it to be efficient, fast and normalized.
虽然我很欣赏这句话,“如果您的业务规则不在您的数据库中,这只是一个建议”,但我也认为您不应该设计数据库来强制执行业务规则,您应该将其设计为高效、快速和规范化。
That said, as others have noted above, there is no "perfect design", the tool has to fit the job. But using business entities can really help with maintenance and productivity, since you know where to go to modify business logic, and objects can model real-world concepts in an intuitive way.
也就是说,正如其他人上面提到的,没有“完美的设计”,工具必须适合工作。但是,使用业务实体可以真正帮助维护和提高生产率,因为您知道如何修改业务逻辑,并且对象可以以一种直观的方式建模真实世界的概念。
#20
2
Eric,
埃里克,
No one is stopping you from choosing the framework/approach that you would wish. If you are going to go the "data driven/stored procedure-powered" path, then by all means, go for it! Especially if it really, really helps you deliver your applications on-spec and on-time.
没有人阻止你选择你想要的框架/方法。如果您要走“数据驱动/存储过程驱动”路径,那么无论如何,一定要去实现它!特别是如果它真的,真的,真的帮助您交付您的应用程序在规格和时间。
The caveat being (a flipside to your question that is), ALL of your business rules should be on stored procedures, and your application is nothing more than a thin client.
需要注意的是(这是问题的另一面),您的所有业务规则都应该位于存储过程中,您的应用程序只不过是一个瘦客户机。
That being said, same rules apply if you do your application in OOP : be consistent. Follow OOP's tenets, and that includes creating entity objects to represent your domain models.
也就是说,如果您在OOP中执行应用程序,同样的规则也适用:保持一致。遵循OOP的原则,包括创建实体对象来表示域模型。
The only real rule here is the word consistency. Nobody is stopping you from going DB-centric. No one is stopping you from doing old-school structured (aka, functional/procedural) programs. Hell, no one is stopping anybody from doing COBOL-style code. BUT an application has to be very, very consistent once going down this path, if it wishes to attain any degree of success.
这里唯一的规则是一致性这个词。没有人阻止你以db为中心。没有人会阻止你去做老式的结构化(即功能/程序)程序。天哪,没人阻止任何人做代码代码。但是一个应用程序必须非常非常一致,如果它希望获得任何程度的成功,它就会沿着这条路径走下去。
#21
2
I'm really not sure what you consider "Enterprise Applications". But I'm getting the impression you are defining it as an Internal Application where the RDBMS would be set in stone and the system wouldn't have to be interoperable with any other systems whether internal or external.
我真的不确定您认为什么是“企业应用程序”。但是我得到的印象是,您将它定义为一个内部应用程序,其中RDBMS将被设置为stone,并且系统不必与任何其他系统(无论是内部的还是外部的)互操作。
But what if you had a database with 100 tables which equate to 4 Stored Procedures for each table just for basic CRUD operations that's 400 stored procedures which need to be maintained and aren't strongly-typed so are susceptible to typos nor can be Unit Tested. What happens when you get a new CTO who is an Open Source Evangelist and wants to change the RDBMS from SQL Server to MySql?
但是,如果有一个数据库,它有100个表,每个表对应4个存储过程,而每个表对应的基本CRUD操作是400个需要维护的存储过程,并且不是强类型的,因此很容易出现拼写错误,也不能进行单元测试。当您得到一个新的CTO,他是一个开放源码的布道者,并且希望将RDBMS从SQL服务器更改为MySql时,会发生什么?
A lot of software today whether Enterprise Applications or Products are using SOA and have some requirements for exposing Web Services, at least the software I am and have been involved with do. Using your approach you would end up exposing a Serialized DataTable or DataRows. Now this may be deemed acceptable if the Client is guaranteed to be .NET and on an internal network. But when the Client is not known then you should be striving to Design an API which is intuitive and in most cases you would not want to be exposing the Full Database schema. I certainly wouldn't want to explain to a Java developer what a DataTable is and how to use it. There's also the consideration of Bandwith and payload size and serialized DataTables, DataSets are very heavy.
现在有很多软件,无论是企业应用程序还是产品都在使用SOA,并且有一些公开Web服务的需求,至少我所使用的软件是这样的。使用您的方法,您最终将公开一个序列化的DataTable或DataRows。如果客户端被保证为。net和内部网络,那么这可能被认为是可以接受的。但是,当客户端不为人所知时,您应该努力设计一个直观的API,在大多数情况下,您不希望公开完整的数据库模式。我当然不想向Java开发人员解释什么是DataTable,以及如何使用它。还有对带宽和有效负载大小和序列化数据的考虑,数据集非常重。
There is no silver bullet with software design and it really depends on where the priorities lie, for me it's in Unit Testable code and loosely coupled components that can be easily consumed be any client.
没有软件设计的灵丹妙药,它实际上取决于优先级的位置,对我来说,它是单元可测试代码和松散耦合的组件,可以方便地用于任何客户端。
just my 2 cents
只是我2美分
#22
2
I'd like to offer another angle to the problem of distance between OO and RDB: history.
我想从另一个角度来讨论OO和RDB之间的距离问题:历史。
Any software has a model of reality that is to some degree an abstraction of reality. No computer program can capture all the complexities of reality, and programs are written just to solve a set of problems from reality. Therefore any software model is a reduction of reality. Sometimes the software model forces reality to reduce itself. Like when you want the car rental company to reserve any car for you as long as it is blue and has alloys, but the operator can't comply because your request won't fit in the computer.
任何软件都有一个现实的模型,在某种程度上是对现实的抽象。没有一个计算机程序能够捕获现实的所有复杂性,而编写程序只是为了从现实中解决一系列问题。因此,任何软件模型都是对现实的贬低。有时,软件模型迫使现实自我缩小。就像你想让汽车租赁公司为你保留任何一辆车一样,只要它是蓝色的和有合金的,但是运营商不能答应,因为你的要求不适合在电脑上。
RDB comes from a very old tradition of putting information into tables, called accounting. Accounting was done on paper, then on punch cards, then in computers. But accounting is already a reduction of reality. Accounting has forced people to follow its system so long that it has become accepted reality. That's why it is relatively easy to make computer software for accounting, accounting has had its information model, long before the computer came along.
RDB源自一个非常古老的传统,将信息放入表中,称为记帐。会计是在纸上完成的,然后是穿孔卡片,然后是计算机。但是会计已经是现实的减少。会计迫使人们长期遵循它的制度,以至于它已经成为公认的现实。这就是为什么制造会计用的计算机软件相对容易,会计在计算机出现之前就有了它的信息模型。
Given the importance of good accounting systems, and the acceptance you get from any business managers, these systems have become very advanced. The database foundations are now very solid and noone hesitates about keeping vital data in something so trustworthy.
考虑到良好的会计系统的重要性,以及你从任何业务经理那里得到的认可,这些系统已经变得非常先进。数据库基础现在非常坚实,没有人会犹豫是否要将重要数据保存在如此值得信赖的东西中。
I guess that OO must have come along when people have found that other aspects of reality are harder to model than accounting (which is already a model). OO has become a very successful idea, but persistance of OO data is relatively underdeveloped. RDB/Accounting has had easy wins, but OO is a much larger field (basically everything that isn't accounting).
当人们发现现实中的其他方面比会计更难建模时(会计已经是一个模型),我猜想OO一定会出现。OO已经成为一个非常成功的想法,但是OO数据的持久性相对不发达。RDB/Accounting容易获胜,但OO是一个更大的领域(基本上所有的东西都不是Accounting)。
So many of us have wanted to use OO but we still want safe storage of our data. What can be safer than to store our data the same way as the esteemed accounting system does? It is an enticing prospects, but we all run into the same pitfalls. Very few have taken the trouble to think of OO persistence compared to the massive efforts by the RDB industry, who has had the benefit of accounting's tradition and position.
我们中的许多人都想使用OO,但我们仍然希望数据的安全存储。还有什么比像受人尊敬的会计系统那样存储我们的数据更安全的呢?这是一个诱人的前景,但我们都遇到了同样的陷阱。与RDB行业的巨大努力相比,很少有人费心去思考OO持久性,RDB行业得益于会计的传统和地位。
Prevayler and db4o are some suggestions, I'm sure there are others I haven't heard of, but none have seemed to get half the press as, say, hibernation.
普雷维勒(Prevayler)和db4o给出了一些建议,我肯定还有其他一些我没有听说过的建议,但似乎没有一个像冬眠(hibernation)这样得到一半的报道。
Storing your objects in good old files doesn't even seem to be taken seriously for multiuser applications, and especially web applications.
对于多用户应用程序,尤其是web应用程序,将对象存储在良好的旧文件中似乎都不被重视。
In my everyday struggle to close the chasm between OO and RDB I use OO as much as possible but try to keep inheritance to a minimum. I don't often use SPs. I'll use the advanced query stuff only in aspects that look like accounting.
在我努力消除OO和RDB之间的鸿沟的日常工作中,我尽可能多地使用OO,但尽量将继承保持在最低限度。我不经常使用SPs。我将只在类似会计学的方面使用高级查询。
I'll be happily supprised when the chasm is closed for good. I think the solution will come when Oracle launches something like "Oracle Object Instance Base". To really catch on, it will have to have a reassuring name.
当鸿沟永远封闭的时候,我将会很高兴。我认为当Oracle启动“Oracle对象实例库”时,解决方案就会出现。要真正流行起来,它必须有一个让人放心的名字。
#23
1
Not a lot of time at the moment, but just off the top of my head...
现在不是很多时间,但就在我的头顶上……
The entity model lets you give a consistent interface to the database (and other possible systems) even beyond what a stored procedure interface can do. By using enterprise-wide business models you can make sure that all applications affect the data consistently which is a VERY important thing. Otherwise you end up with bad data, which is just plain evil.
实体模型允许您为数据库(以及其他可能的系统)提供一致的接口,甚至超出存储过程接口的功能。通过使用企业范围的业务模型,您可以确保所有应用程序都一致地影响数据,这是非常重要的事情。否则,你就会得到糟糕的数据,这简直就是罪恶。
If you only have one application then you don't really have an "enterprise" system, regardless of how big that application or your data are. In that case you can use an approach similar to what you talk about. Just be aware of the work that will be needed if you decide to grow your systems in the future.
如果您只有一个应用程序,那么无论应用程序或数据有多大,您都没有真正的“企业”系统。在这种情况下,您可以使用类似于您所谈论的方法。如果您决定在未来发展您的系统,请注意需要做的工作。
Here are a few things that you should keep in mind (IMO) though:
以下是一些你应该记住的事情(在我看来):
- Generated SQL code is bad (exceptions to follow). Sorry, I know that a lot of people think that it's a huge time saver, but I've never found a system that could generate more efficient code than what I could write and often the code is just plain horrible. You also often end up generating a ton of SQL code that never gets used. The exception here is very simple patterns, like maybe lookup tables. A lot of people get carried away on it though.
- 生成的SQL代码很糟糕(以下是例外)。对不起,我知道很多人认为这是一个巨大的节省时间的系统,但我从来没有发现一个系统可以产生比我所能写的更有效的代码,而且代码通常是非常糟糕的。您还常常生成大量从未使用过的SQL代码。这里的例外是非常简单的模式,比如查找表。然而,很多人都被它迷住了。
- Entities <> Tables (or even logical data model entities necessarily). A data model often has data rules that should be enforced as closely to the database as possible which can include rules around how table rows relate to each other or other similar rules that are too complex for declarative RI. These should be handled in stored procedures. If all of your stored procedures are simple CRUD procs, you can't do that. On top of that, the CRUD model usually creates performance issues because it doesn't minimize round trips across the network to the database. That's often the biggest bottleneck in an enterprise application.
- 实体<>表(甚至逻辑数据模型实体必须)。数据模型通常有数据规则,这些规则应该尽可能紧密地强制到数据库中,这些规则可以包括关于表行如何相互关联的规则,或者对于声明性RI来说过于复杂的其他类似规则。这些应该在存储过程中处理。如果您的所有存储过程都是简单的CRUD过程,那么您不能这样做。除此之外,CRUD模型通常会产生性能问题,因为它不会最小化跨网络到数据库的往返。这通常是企业应用程序中最大的瓶颈。
#24
1
Sometimes, your application and data layer are not that tightly coupled. For example, you may have a telephone billing application. You later create a separate application which monitors phone usage to a) better advertise to you b) optimise your phone plan.
有时候,应用程序和数据层没有那么紧密地耦合。例如,您可能有一个电话计费应用程序。之后你创建了一个单独的应用程序来监控手机的使用情况a)更好地为你做广告b)优化你的手机计划。
These applications have different concerns and data requirements (even the data is coming out of the same database), they would drive different designs. Your code base can end up an absolute mess (in either application) and a nightmare to maintain if you let the database drive the code.
这些应用程序有不同的关注点和数据需求(即使数据来自同一个数据库),它们将驱动不同的设计。如果让数据库驱动代码,您的代码库可能最终会变得一团糟(在任何一个应用程序中都是如此),而且维护起来会很麻烦。
#25
1
Applications that have domain logic separated from the data storage logic are adaptable to any kind of data source (database or otherwise) or UI (web or windows(or linux etc.)) application.
将域逻辑与数据存储逻辑分离的应用程序适用于任何类型的数据源(数据库或其他)或UI (web或windows(或linux等))应用程序。
Your pretty much stuck in your database, which isn't bad if your with a company who is satisfied with the current database system your using. However, because databases evolve overtime there might be a new database system that is really neat and new that your company wants to use. What if they wanted to switch to a web services method of data access (like Service Orientated architecture sometime does). You might have to port your stored procedures all over the place.
如果你的公司对你使用的当前数据库系统感到满意,那么你的数据库就会陷入困境。然而,由于数据库随着时间的推移不断发展,可能会有一个新的数据库系统,非常干净和新颖,您的公司希望使用它。如果他们想要切换到数据访问的web服务方法(比如某个时候的面向服务的体系结构),会怎么样呢?您可能需要到处移植存储过程。
Also the domain logic abstracts away the UI, which can be more important in large complex systems that have ever evolving UIs (especially when they are constantly searching for more customers).
此外,领域逻辑还抽象出UI,这在曾经发展过UI的大型复杂系统中可能更为重要(特别是当它们不断地搜索更多的客户时)。
Also, while I agree that there is no definitive answer to the question of stored procedures versus domain logic. I'm in the domain logic camp (and I think they are winning over time), because I believe that elaborate stored procedures are harder to maintain than elaborate domain logic. But that's a whole other debate
此外,尽管我同意存储过程与域逻辑之间的关系并没有明确的答案。我在域逻辑阵营(我认为他们会赢得时间),因为我认为复杂的存储过程比复杂的域逻辑更难维护。但这是另一场辩论
#26
0
I think that you are just used to writing a specific kind of application, and solving a certain kind of problem. You seem to be attacking this from a "database first" perspective. There are lots of developers out there where data is persisted to a DB but performance is not a top priority. In lots of cases putting an abstraction over the persistence layer simplifies code greatly and the performance cost is a non-issue.
我认为你只是习惯于写一种特定的应用,并解决某种问题。您似乎是从“数据库优先”的角度来攻击这个问题的。有很多开发人员将数据持久化到数据库中,但是性能并不是他们的首要任务。在许多情况下,将抽象放在持久性层之上可以极大地简化代码,并且性能成本也不是问题。
Whatever you are doing, it's not OOP. It's not wrong, it's just not OOP, and it doesn't make sense to apply your solutions to every othe problem out there.
不管你在做什么,都不是OOP。这并不是错的,它只是没有OOP,并且把你的解决方案应用到每一个问题上是没有意义的。
#27
0
Interesting question. A couple thoughts:
有趣的问题。几个想法:
- How would you unit test if all of your business logic was in your database?
- 如果所有的业务逻辑都在数据库中,那么如何进行单元测试呢?
- Wouldn't changes to your database structure, specifically ones that affect several pages in your app, be a major hassle to change throughout the app?
- 改变你的数据库结构,特别是影响你的应用中的几个页面的结构,会不会成为整个应用中最麻烦的事情?
#28
0
Good Question!
好问题!
One approach I rather like is to create an iterator/generator object that emits instances of objects that are relevant to a specific context. Usually this object wraps some underlying database access stuff, but I don't need to know that when using it.
我比较喜欢的一种方法是创建一个迭代器/生成器对象,该对象发出与特定上下文相关的对象实例。通常这个对象封装了一些底层数据库访问内容,但是我不需要在使用它时知道这些内容。
For example,
例如,
An AnswerIterator object generates AnswerIterator.Answer objects. Under the hood it's iterating over a SQL Statement to fetch all the answers, and another SQL statement to fetch all related comments. But when using the iterator I just use the Answer object that has the minimum properties for this context. With a little bit of skeleton code this becomes almost trivial to do.
AnswerIterator对象生成AnswerIterator。回答对象。在底层,它遍历一个SQL语句以获取所有答案,而另一个SQL语句则获取所有相关的注释。但是在使用迭代器时,我只使用具有此上下文的最小属性的Answer对象。使用一些框架代码,这就变得非常简单。
I've found that this works well when I have a huge dataset to work on, and when done right, it gives me small, transient objects that are relatively easy to test.
我发现,当我有一个庞大的数据集要处理时,它就能很好地工作,如果处理得当,它会给我提供相对容易测试的小的、短暂的对象。
It's basically a thin veneer over the Database Access stuff, but it still gives me the flexibility of abstracting it when I need to.
它基本上只是数据库访问的一种虚饰,但是当我需要时,它仍然为我提供了抽象它的灵活性。
#29
0
The objects in my apps tend to relate one-to-one to the database, but I'm finding using Linq To Sql rather than sprocs makes it much easier writing complicated queries, especially being able to build them up using the deferred execution. e.g. from r in Images.User.Ratings where etc. This saves me trying to work out several join statements in sql, and having Skip & Take for paging also simplifies the code rather than having to embed the row_number & 'over' code.
我的应用程序中的对象倾向于一对一地与数据库相关联,但我发现使用Linq to Sql而不是sprocs更容易编写复杂的查询,特别是能够使用延迟执行构建它们。从图片中的r开始。这使我不必尝试在sql中构造几个连接语句,并且使用Skip & Take进行分页也可以简化代码,而不必嵌入row_number和'over'代码。
#30
0
Why stop at entity objects? If you don't see the value with entity objects in an enterprise level app, then just do your data access in a purely functional/procedural language and wire it up to a UI. Why not just cut out all the OO "fluff"?
为什么要停在实体对象上?如果您在企业级应用程序中没有看到实体对象的值,那么只需使用纯函数/过程性语言进行数据访问,并将其连接到UI。为什么不剪掉所有的OO“fluff”呢?
#1
59
I think it comes down to how complicated the "logic" of the application is, and where you have implemented it. If all your logic is in stored procedures, and all your application does is call those procedures and display the results, then developing entity objects is indeed a waste of time. But for an application where the objects have rich interactions with one another, and the database is just a persistence mechanism, there can be value to having those objects.
我认为这取决于应用程序的“逻辑”有多复杂,以及在哪里实现了它。如果所有的逻辑都在存储过程中,而应用程序所做的就是调用这些过程并显示结果,那么开发实体对象确实是浪费时间。但是对于一个对象之间具有丰富交互的应用程序,并且数据库只是一个持久性机制,拥有这些对象是有价值的。
So, I'd say there is no one-size-fits-all answer. Developers do need to be aware that, sometimes, trying to be too OO can cause more problems than it solves.
所以,我想说,没有一种方法适合所有人。开发人员确实需要意识到,有时候太过OO会导致比它解决的问题更多的问题。
#2
27
Theory says that highly cohesive, loosely coupled implementations are the way forward.
理论认为,高度内聚、松散耦合的实现是前进的方向。
So I suppose you are questioning that approach, namely separating concerns.
所以我想你是在质疑这种方法,即分离关注点。
Should my aspx.cs file be interacting with the database, calling a sproc, and understanding IDataReader?
应该我的aspx。cs文件正在与数据库交互,调用sproc,并理解IDataReader?
In a team environment, especially where you have less technical people dealing with the aspx portion of the application, I don't need these people being able to "touch" this stuff.
在团队环境中,特别是当你的技术人员很少处理应用程序的aspx部分时,我不需要这些人能够“触摸”这些东西。
Separating my domain from my database protects me from structural changes in the database, surely a good thing? Sure database efficacy is absolutely important, so let someone who is most excellent at that stuff deal with that stuff, in one place, with as little impact on the rest of the system as possible.
将域从数据库中分离出来可以保护我不受数据库中结构变化的影响,这肯定是件好事吗?当然,数据库的有效性是绝对重要的,所以让那些最擅长数据库的人在一个地方处理这些东西,对系统其他部分的影响尽可能小。
Unless I am misunderstanding your approach, one structural change in the database could have a large impact area with the surface of your application. I see that this separation of concerns enables me and my team to minimise this. Also any new member of the team should understand this approach better.
除非我误解了您的方法,否则数据库中的一个结构更改可能会对应用程序的表面产生很大的影响。我看到这种分离的关注点使我和我的团队能够将这一点最小化。团队中的任何新成员都应该更好地理解这种方法。
Also, your approach seems to advocate the business logic of your application to reside in your database? This feels wrong to me, SQL is really good at querying data, and not, imho, expressing business logic.
而且,您的方法似乎支持应用程序的业务逻辑驻留在数据库中?在我看来,这是不对的,SQL确实擅长查询数据,而不是表达业务逻辑。
Interesting thought though, although it feels one step away from SQL in the aspx, which from my bad old unstructured asp days, fills me with dread.
然而,有趣的想法是,尽管在aspx中,它感觉离SQL只有一步之遥,而在我以前糟糕的非结构化asp时代,SQL使我充满了恐惧。
#3
25
One reason - separating your domain model from your database model.
一个原因是将域模型与数据库模型分离。
What I do is use Test Driven Development so I write my UI and Model layers first and the Data layer is mocked, so the UI and model is build around domain specific objects, then later I map these objects to what ever technology I'm using the the Data Layer. Its a bad idea to let the database structure determine the design of your application. Where possible write the app first and let that influence the structure of your database, not the other way around.
我所做的是使用测试驱动开发,我首先编写UI和模型层,然后对数据层进行模拟,因此UI和模型是围绕领域特定对象构建的,然后我将这些对象映射到我使用数据层的任何技术。让数据库结构决定应用程序的设计不是一个好主意。如果可能的话,首先编写应用程序,让它影响数据库的结构,而不是反过来。
#4
22
For me it boils down to I don't want my application to be concerned with how the data is stored. I'll probably get slapped for saying this...but your application is not your data, data is an artifact of the application. I want my application to be thinking in terms of Customers, Orders and Items, not a technology like DataSets, DataTables and DataRows...cuz who knows how long those will be around.
对我来说,它归结为我不希望我的应用程序关心数据是如何存储的。我可能会因为这样说而被打上耳光……但是您的应用程序不是您的数据,数据是应用程序的工件。我希望我的应用程序考虑的是客户、订单和项目,而不是数据集、DataTables和DataRows等技术。因为谁知道它们会存在多久。
I agree that there is always a certain amount of coupling, but I prefer that coupling to reach upwards rather than downwards. I can tweak the limbs and leaves of a tree easier than I can alter it's trunk.
我同意总有一定数量的耦合,但我宁愿耦合向上而不是向下。我可以更容易地调整树的四肢和叶子,而不是我可以改变它的树干。
I tend to reserve sprocs for reporting as the queries do tend to get a little nastier than the applications general data access.
我倾向于保留sprocs用于报告,因为查询比应用程序一般的数据访问更糟糕。
I also tend to think with proper unit testing early on that scenario's like that one column not being persisted is likely not to be a problem.
我也倾向于认为,在这个场景的早期进行适当的单元测试,就像没有持久化的一列很可能不是问题。
#5
16
Eric, You are dead on. For any really scalable / easily maintained / robust application the only real answer is to dispense with all the garbage and stick to the basics.
埃里克,你死定了。对于任何真正可伸缩/容易维护/健壮的应用程序来说,唯一真正的答案是不使用所有的垃圾并坚持基本原则。
I've followed a similiar trajectory with my career and have come to the same conclusions. Of course, we're considered heretics and looked at funny. But my stuff works and works well.
在我的职业生涯中,我遵循着相似的轨迹,并得出了相同的结论。当然,我们被认为是异端,而且看起来很有趣。但是我的东西很好用。
Every line of code should be looked at with suspicion.
每一行代码都应该被怀疑。
#6
11
I would like to answer with an example similar to the one you proposed.
我想用一个类似于你提出的例子来回答。
On my company I had to build a simple CRUD section for products, I build all my entities and a separate DAL. Later another developer had to change a related table and he even renamed several fields. The only file I had to change to update my form was the DAL for that table.
在我的公司,我必须为产品构建一个简单的CRUD部分,我构建所有实体和一个单独的DAL。后来,另一个开发人员不得不更改一个相关的表,他甚至重新命名了几个字段。为了更新表单,我必须更改的唯一文件是该表的DAL。
What (in my opinion) entities brings to a project is:
(在我看来)实体给项目带来的是:
Ortogonality: Changes in one layer might not affect other layers (off course if you make a huge change on the database it would ripple through all the layers but most small changes won't).
Ortogonality:一个层中的更改可能不会影响其他层(当然,如果您对数据库做了巨大的更改,那么它将影响所有层,但大多数小更改不会)。
Testability: You can test your logic with out touching your database. This increases performance on your tests (allowing you to run them more frequently).
可测试性:您可以在不接触数据库的情况下测试逻辑。这提高了测试的性能(允许您更频繁地运行它们)。
Separation of concerns: In a big product you can assign the database to a DBA and he can optimize the hell out of it. Assign the Model to a business expert that has the knowledge necessary to design it. Assign individual forms to developers more experienced on webforms etc..
关注点分离:在大型产品中,您可以将数据库分配给DBA, DBA可以从中进行优化。将模型分配给具有设计模型所需知识的业务专家。将个人表单分配给在web表单等方面更有经验的开发人员。
Finally I would like to add that most ORM mappers support stored procedures since that's what you are using.
最后,我想补充一点,大多数ORM映射器都支持存储过程,因为这正是您所使用的。
Cheers.
欢呼。
#7
8
I think you may be "biting off more than you can chew" on this topic. Ted Neward was not being flippant when he called it the "Vietnam of Computer Science".
我认为你可能在这个话题上“贪多嚼不烂”。Ted Neward称其为“计算机科学的越南”时并不轻率。
One thing I can absolutely guarantee you is that it will change nobody's point of view on the matter, as has been proven so often on innumerable other blogs, forums, podcasts etc.
有一件事我可以向你保证,那就是它不会改变任何人对这件事的看法,就像在无数其他博客、论坛、播客上经常被证明的那样。
It's certainly ok to have open disucssion and debate about a controversial topic, it's just this one has been done so many times that both "sides" have agreed to disagree and just got on with writing software.
对一个有争议的话题进行公开的离题和辩论当然是可以的,只是这个话题已经被做了很多次了,以至于双方都同意不同意,只是继续写软件。
If you want to do some further reading on both sides, see articles on Ted's blog, Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans etc.
如果你想在双方都做进一步的阅读,请参阅Ted的博客,Ayende Rahein, Jimmy Nilson, Scott Bellware, Alt.Net, Stephen Forte, Eric Evans等。
#8
7
@Dan, sorry, that's not the kind of thing I'm looking for. I know the theory. Your statement "is a very bad idea" is not backed up by a real example. We are trying to develop software in less time, with less people, with less mistakes, and we want the ability to easily make changes. Your multi-layer model, in my experience, is a negative in all of the above categories. Especially with regards to making the data model the last thing you do. The physical data model must be an important consideration from day 1.
@Dan,对不起,那不是我要找的东西。我知道这个理论。你所说的“是一个非常糟糕的想法”没有一个真实的例子来支持。我们正试图用更少的时间、更少的人员、更少的错误来开发软件,我们希望能够轻松地进行更改。根据我的经验,你的多层模型在以上所有类别中都是负面的。尤其是关于将数据模型作为最后一件事。从第一天开始,物理数据模型就必须是一个重要的考虑因素。
#9
4
I found your question really interesting.
Usually I need entities objects to encapsulate the business logic of an application. It would be really complicated and inadequate to push this logic into the data layer.
What would you do to avoid these entities objects? What solution do you have in mind?
我发现你的问题很有趣。通常,我需要实体对象来封装应用程序的业务逻辑。将这种逻辑推入数据层会非常复杂和不充分。如何避免这些实体对象?你有什么解决办法吗?
#10
4
Entity Objects can facilitate cacheing on the application layer. Good luck caching a datareader.
实体对象可以促进应用程序层上的缓存。好运气缓存一个datareader。
#11
4
We should also talk about the notion what entities really are. When I read through this discussion, I get the impression that most people here are looking at entities in the sense of an Anemic Domain Model. A lot of people are considering the Anemic Domain Model as an antipattern!
我们还应该讨论实体的概念。当我通读这篇讨论时,我得到的印象是,这里的大多数人都是从贫血的领域模型的角度来看待实体的。许多人认为贫血域模型是一种反模式!
There is value in rich domain models. That is what Domain Driven Design is all about. I personally believe that OO is a way to conquer complexity. This means not only technical complexity (like data-access, ui-binding, security ...) but also complexity in the business domain!
在丰富的领域模型中有价值。这就是领域驱动设计的意义所在。我个人认为OO是一种克服复杂性的方法。这不仅意味着技术复杂性(如数据访问、ui绑定、安全性……),还意味着业务领域的复杂性!
If we can apply OO techniques to analyze, model, design and implement our business problems, this is a tremendous advantage for maintainability and extensibility of non-trivial applications!
如果我们能够应用OO技术来分析、建模、设计和实现我们的业务问题,这对于非平凡应用程序的可维护性和可扩展性来说是一个巨大的优势!
There are differences between your entities and your tables. Entities should represent your model, tables just represent the data-aspect of your model!
实体和表之间存在差异。实体应该代表您的模型,表仅仅代表模型的数据方面!
It is true that data lives longer than apps, but consider this quote from David Laribee: Models are forever ... data is a happy side effect.
数据确实比应用程序寿命长,但想想大卫·拉里比(David Laribee)的话:模型是永恒的……数据是一个好的副作用。
Some more links on this topic:
更多关于这个话题的链接:
-
Why Setters and Getters are evil
为什么定居者和getter都是邪恶的
-
返回纯OO
-
POJO和NOJO
-
超级模型第2部分
-
TDD、模拟和设计
#12
4
Really interesting question. Honestly I can not prove why entities are good. But I can share my opinion why I like them. Code like
很有趣的问题。老实说,我无法证明为什么实体是好的。但是我可以分享我喜欢它们的原因。代码
void exportOrder(Order order, String fileName){...};
is not concerned where order came from - from DB, from web request, from unit test, etc. It makes this method more explicitly declare what exactly it requires, instead of taking DataRow and documenting which columns it expects to have and which types they should be. Same applies if you implement it somehow as stored procedure - you still need to push record id to it, while it not necessary should be present in DB.
不关心顺序来自哪里——来自DB、web请求、单元测试等等。它使这个方法更明确地声明它所需要的内容,而不是使用DataRow并记录它希望拥有的列以及它们应该是什么类型。同样,如果您以某种方式实现它作为存储过程——您仍然需要将记录id推到它,而不需要在DB中存在。
Implementation of this method would be done based on Order abstraction, not based on how exactly it is presented in DB. Most of such operations which I implemented really do not depend on how this data is stored. I do understand that some operations require coupling with DB structure for perfomance and scalability purposes, just in my experience there are not too much of them. In my experience very often it is enough to know that Person has .getFirstName() returning String, and .getAddress() returning Address, and address has .getZipCode(), etc - and do not care which tables are involed to store that data.
该方法的实现将基于订单抽象,而不是基于如何在DB中显示它。我实现的大多数此类操作实际上并不依赖于如何存储这些数据。我确实理解,出于性能和可扩展性的目的,有些操作需要与DB结构耦合,根据我的经验,这些操作并不多。在我的经验中,通常只要知道这个人有. getfirstname()返回字符串,. getaddress()返回地址,地址有. getzipcode()等,就足够了,而且不需要关心要使用哪些表来存储该数据。
If you have to deal with such problems as you described, like when additional column breaks report perfomance, then for your tasks DB is a critical part, and you indeed should be as close as possible to it. While entities can provide some convenient abstractions they can hide some important details as well.
如果您必须处理您所描述的这些问题,比如当附加的列中断报表执行时,那么对于您的任务DB是一个关键部分,您确实应该尽可能地接近它。虽然实体可以提供一些方便的抽象,但是它们也可以隐藏一些重要的细节。
Scalability is interesting point here - most of websites which require enormous scalability (like facebook, livejournal, flickr) tend to use DB-ascetic approach, when DB is used as rare as possible and scalability issues are solved by caching, especially by RAM usage. http://highscalability.com/ has some interesting articles on it.
可扩展性在这里是很有趣的一点——大多数需要大量可扩展性的网站(如facebook、livejournal、flickr)都倾向于使用DB-ascetic方法,当DB尽可能少地使用时,可扩展性问题通过缓存(特别是RAM的使用)来解决。http://highscalability.com/有一些有趣的文章。
#13
4
There are other good reasons for entity objects besides abstraction and loose coupling. One of the things I like most is the strong typing that you can't get with a DataReader or a DataTable. Another reason is that when done well, proper entity classes can make the code more maintanable by using first-class constructs for domain-specific terms that anyone looking at the code is likely to understand rather than a bunch of strings with field names in them used for indexing a DataRow. Stored procedures are really orthogonal to the use of an ORM since a lot of mapping frameworks give you the ability to map to sprocs.
除了抽象和松耦合之外,实体对象还有其他好的原因。我最喜欢的一件事是,你无法使用DataReader或DataTable的强类型。另一个原因是,如果做得很好,适当的实体类可以通过为特定于域的术语使用一流的构造来使代码更易于维护,任何查看代码的人都可能理解这些术语,而不是使用字段名作为索引的字符串。存储过程与ORM的使用是正交的,因为许多映射框架都允许您映射到sprocs。
I wouldn't consider sprocs + datareaders a substitute for a good ORM. With stored procedures, you're still constrained by, and tightly-coupled to, the procedure's type signature, which uses a different type system than the calling code. Stored procedures can be subject to modification to acommodate additional options and schema changes. An alternative to stored procedures in the case where the schema is subject to change is to use views--you can map objects to views and then re-map views to the underlying tables when you change them.
我不认为sprocs + datareaders是一个好的ORM的替代品。对于存储过程,您仍然受到过程的类型签名的限制,并与之紧密耦合,该签名使用与调用代码不同的类型系统。存储过程可以修改为acommodate附加选项和模式更改。在模式可能发生更改的情况下,存储过程的另一种替代方法是使用视图——您可以将对象映射到视图,然后在更改视图时将视图重新映射到底层表。
I can understand your aversion to ORMs if your experience mainly consists of Java EE and CSLA. You might want to have a look at LINQ to SQL, which is a very lightweight framework and is primarily a one-to-one mapping with the database tables but usually only needs minor extension for them to be full-blown business objects. LINQ to SQL can also map input and output objects to stored procedures' paramaters and results.
如果您的经验主要是Java EE和CSLA,我可以理解您对orm的反感。您可能想了解一下LINQ到SQL,这是一个非常轻量级的框架,主要是与数据库表的一对一映射,但通常只需要对它们进行很小的扩展,就可以使它们成为成熟的业务对象。LINQ to SQL还可以将输入和输出对象映射到存储过程的参数和结果。
The ADO.NET Entity framework has the added advantage that your database tables can be viewed as entity classes inheriting from each other, or as columns from multiple tables aggregated into a single entity. If you need to change the schema, you can change the mapping from the conceptual model to the storage schema without changing the actual application code. And again, stored procedures can be used here.
ADO。NET实体框架还有一个额外的优点,即可以将数据库表视为相互继承的实体类,或者将多个表的列聚合为一个实体。如果需要更改模式,可以将映射从概念模型更改为存储模式,而无需更改实际的应用程序代码。同样,存储过程也可以在这里使用。
I think that more IT projects in enterprises fail because of unmaintainability of the code or poor developer productivity (which can happen from, e.g., context switching between sproc-writing and app-writing) than scalability problems of an application.
我认为,与应用程序的可伸缩性问题相比,企业中的IT项目失败的更多原因是代码的不可维护性或开发人员的生产力低下(这可能发生在sproc编写和应用程序编写之间的上下文切换)。
#14
3
I would also like to add to Dan's answer that separating both models could enable your application to be run on different database servers or even database models.
我还想补充Dan的答案,即分离这两个模型可以使您的应用程序在不同的数据库服务器上运行,甚至可以在数据库模型上运行。
#15
3
What if you need to scale your app by load balancing more than one web server? You could install the full app on all web servers, but a better solution is to have the web servers talk to an application server.
如果需要通过加载多个web服务器来平衡应用程序,该怎么办?您可以在所有web服务器上安装完整的应用程序,但是更好的解决方案是让web服务器与应用服务器对话。
But if there aren't any entity objects, they won't have very much to talk about.
但是如果没有任何实体对象,它们就不会有太多要讨论的内容。
I'm not saying that you shouldn't write monoliths if its a simple, internal, short life application. But as soon as it gets moderately complex, or it should last a significant amount of time, you really need to think about a good design.
我并不是说,如果这是一个简单的、内部的、短寿命的应用程序,你就不应该写“巨石”。但是一旦它变得适度复杂,或者它应该持续很长一段时间,你就需要考虑一个好的设计。
This saves time when it comes to maintaining it.
这节省了维护的时间。
By splitting application logic from presentation logic and data access, and by passing DTOs between them, you decouple them. Allowing them to change independently.
通过将应用程序逻辑从表示逻辑和数据访问中分离出来,并在它们之间传递dto,可以对它们进行解耦。允许他们独立地改变。
#16
3
You might find this post on comp.object interesting.
你可能会在com .object上发现这篇文章很有趣。
I'm not claiming to agree or disagree but it's interesting and (I think) relevant to this topic.
我并不是说我同意或不同意,但它很有趣并且(我认为)与这个话题相关。
#17
3
A question: How do you handle disconnected applications if all your business logic is trapped in the database?
问题:如果所有业务逻辑都被困在数据库中,您如何处理断开连接的应用程序?
In the type of Enterprise application I'm interested in, we have to deal with multiple sites, some of them must be able to function in a disconnected state.
If your business logic is encapsulated in a Domain layer that is simple to incorporate into various application types -say, as a dll
- then I can build applications that are aware of the business rules and are able, when necessary, to apply them locally.
在我感兴趣的企业应用程序类型中,我们必须处理多个站点,其中一些站点必须能够在断开连接的状态下运行。如果您的业务逻辑封装在一个域层中,这个域层可以简单地合并到各种应用程序类型中(例如,作为一个dll),那么我就可以构建知道业务规则的应用程序,并在必要时能够在本地应用它们。
In keeping the Domain layer in stored procedures on the database you have to stick with a single type of application that needs a permanent line-of-sight to the database.
为了在数据库的存储过程中保持域层,您必须使用一种类型的应用程序,这种应用程序需要数据库的永久视线。
It's ok for a certain class of environments, but it certainly doesn't cover the whole spectrum of Enterprise applications.
对于特定类型的环境来说,这是可以接受的,但它肯定不包括企业应用程序的整个范围。
#18
2
@jdecuyper, one maxim I repeat to myself often is "if your business logic is not in your database, it is only a recommendation". I think Paul Nielson said that in one of his books. Application layers and UI come and go, but data usually lives for a very long time.
@jdecuyper,我经常对自己说的一句话是“如果你的业务逻辑不在你的数据库中,那它只是一个建议”。我认为保罗·尼尔森在他的一本书中说过。应用程序层和UI来来去去,但数据通常会存在很长一段时间。
How do I avoid entity objects? Stored procedures mostly. I also freely admit that business logic tends to reach through all layers in an application whether you intend it to or not. A certain amount of coupling is inherent and unavoidable.
如何避免实体对象?主要是存储过程。我还坦率地承认,无论您是否有意,业务逻辑都倾向于贯穿应用程序的所有层。一定数量的耦合是不可避免的。
#19
2
I have been thinking about this same thing a lot lately; I was a heavy user of CSLA for a while, and I love the purity of saying that "all of your business logic (or at least as much as is reasonably possible) is encapsulated in business entities".
我最近一直在思考同样的事情;有一段时间,我一直是CSLA的忠实用户,我喜欢这种纯粹的说法:“您的所有业务逻辑(或至少尽可能多地)都封装在业务实体中”。
I have seen the business entity model provide a lot of value in cases where the design of the database is different than the way you work with the data, which is the case in a lot of business software.
我已经看到,在数据库的设计与处理数据的方式不同的情况下,业务实体模型提供了大量的价值,这在很多业务软件中都是如此。
For example, the idea of a "customer" may consist of a main record in a Customer table, combined with all of the orders the customer has placed, as well as all the customer's employees and their contact information, and some of the properties of a customer and its children may be determined from lookup tables. It's really nice from a development standpoint to be able to work with the Customer as a single entity, since from a business perspective, the concept of Customer contains all of these things, and the relationships may or may not be enforced in the database.
例如,“客户”的概念可能由一个主要记录客户表,结合所有的客户订单,以及所有客户的员工和他们的联系信息,和一些客户的性质和它的孩子可以从查找表来确定。从开发的角度来看,能够将客户作为一个单独的实体来工作是非常好的,因为从业务的角度来看,客户的概念包含了所有这些东西,并且关系在数据库中可能被执行,也可能不被执行。
While I appreciate the quote that "if your business rule is not in your database, it's only a suggestion", I also believe that you shouldn't design the database to enforce business rules, you should design it to be efficient, fast and normalized.
虽然我很欣赏这句话,“如果您的业务规则不在您的数据库中,这只是一个建议”,但我也认为您不应该设计数据库来强制执行业务规则,您应该将其设计为高效、快速和规范化。
That said, as others have noted above, there is no "perfect design", the tool has to fit the job. But using business entities can really help with maintenance and productivity, since you know where to go to modify business logic, and objects can model real-world concepts in an intuitive way.
也就是说,正如其他人上面提到的,没有“完美的设计”,工具必须适合工作。但是,使用业务实体可以真正帮助维护和提高生产率,因为您知道如何修改业务逻辑,并且对象可以以一种直观的方式建模真实世界的概念。
#20
2
Eric,
埃里克,
No one is stopping you from choosing the framework/approach that you would wish. If you are going to go the "data driven/stored procedure-powered" path, then by all means, go for it! Especially if it really, really helps you deliver your applications on-spec and on-time.
没有人阻止你选择你想要的框架/方法。如果您要走“数据驱动/存储过程驱动”路径,那么无论如何,一定要去实现它!特别是如果它真的,真的,真的帮助您交付您的应用程序在规格和时间。
The caveat being (a flipside to your question that is), ALL of your business rules should be on stored procedures, and your application is nothing more than a thin client.
需要注意的是(这是问题的另一面),您的所有业务规则都应该位于存储过程中,您的应用程序只不过是一个瘦客户机。
That being said, same rules apply if you do your application in OOP : be consistent. Follow OOP's tenets, and that includes creating entity objects to represent your domain models.
也就是说,如果您在OOP中执行应用程序,同样的规则也适用:保持一致。遵循OOP的原则,包括创建实体对象来表示域模型。
The only real rule here is the word consistency. Nobody is stopping you from going DB-centric. No one is stopping you from doing old-school structured (aka, functional/procedural) programs. Hell, no one is stopping anybody from doing COBOL-style code. BUT an application has to be very, very consistent once going down this path, if it wishes to attain any degree of success.
这里唯一的规则是一致性这个词。没有人阻止你以db为中心。没有人会阻止你去做老式的结构化(即功能/程序)程序。天哪,没人阻止任何人做代码代码。但是一个应用程序必须非常非常一致,如果它希望获得任何程度的成功,它就会沿着这条路径走下去。
#21
2
I'm really not sure what you consider "Enterprise Applications". But I'm getting the impression you are defining it as an Internal Application where the RDBMS would be set in stone and the system wouldn't have to be interoperable with any other systems whether internal or external.
我真的不确定您认为什么是“企业应用程序”。但是我得到的印象是,您将它定义为一个内部应用程序,其中RDBMS将被设置为stone,并且系统不必与任何其他系统(无论是内部的还是外部的)互操作。
But what if you had a database with 100 tables which equate to 4 Stored Procedures for each table just for basic CRUD operations that's 400 stored procedures which need to be maintained and aren't strongly-typed so are susceptible to typos nor can be Unit Tested. What happens when you get a new CTO who is an Open Source Evangelist and wants to change the RDBMS from SQL Server to MySql?
但是,如果有一个数据库,它有100个表,每个表对应4个存储过程,而每个表对应的基本CRUD操作是400个需要维护的存储过程,并且不是强类型的,因此很容易出现拼写错误,也不能进行单元测试。当您得到一个新的CTO,他是一个开放源码的布道者,并且希望将RDBMS从SQL服务器更改为MySql时,会发生什么?
A lot of software today whether Enterprise Applications or Products are using SOA and have some requirements for exposing Web Services, at least the software I am and have been involved with do. Using your approach you would end up exposing a Serialized DataTable or DataRows. Now this may be deemed acceptable if the Client is guaranteed to be .NET and on an internal network. But when the Client is not known then you should be striving to Design an API which is intuitive and in most cases you would not want to be exposing the Full Database schema. I certainly wouldn't want to explain to a Java developer what a DataTable is and how to use it. There's also the consideration of Bandwith and payload size and serialized DataTables, DataSets are very heavy.
现在有很多软件,无论是企业应用程序还是产品都在使用SOA,并且有一些公开Web服务的需求,至少我所使用的软件是这样的。使用您的方法,您最终将公开一个序列化的DataTable或DataRows。如果客户端被保证为。net和内部网络,那么这可能被认为是可以接受的。但是,当客户端不为人所知时,您应该努力设计一个直观的API,在大多数情况下,您不希望公开完整的数据库模式。我当然不想向Java开发人员解释什么是DataTable,以及如何使用它。还有对带宽和有效负载大小和序列化数据的考虑,数据集非常重。
There is no silver bullet with software design and it really depends on where the priorities lie, for me it's in Unit Testable code and loosely coupled components that can be easily consumed be any client.
没有软件设计的灵丹妙药,它实际上取决于优先级的位置,对我来说,它是单元可测试代码和松散耦合的组件,可以方便地用于任何客户端。
just my 2 cents
只是我2美分
#22
2
I'd like to offer another angle to the problem of distance between OO and RDB: history.
我想从另一个角度来讨论OO和RDB之间的距离问题:历史。
Any software has a model of reality that is to some degree an abstraction of reality. No computer program can capture all the complexities of reality, and programs are written just to solve a set of problems from reality. Therefore any software model is a reduction of reality. Sometimes the software model forces reality to reduce itself. Like when you want the car rental company to reserve any car for you as long as it is blue and has alloys, but the operator can't comply because your request won't fit in the computer.
任何软件都有一个现实的模型,在某种程度上是对现实的抽象。没有一个计算机程序能够捕获现实的所有复杂性,而编写程序只是为了从现实中解决一系列问题。因此,任何软件模型都是对现实的贬低。有时,软件模型迫使现实自我缩小。就像你想让汽车租赁公司为你保留任何一辆车一样,只要它是蓝色的和有合金的,但是运营商不能答应,因为你的要求不适合在电脑上。
RDB comes from a very old tradition of putting information into tables, called accounting. Accounting was done on paper, then on punch cards, then in computers. But accounting is already a reduction of reality. Accounting has forced people to follow its system so long that it has become accepted reality. That's why it is relatively easy to make computer software for accounting, accounting has had its information model, long before the computer came along.
RDB源自一个非常古老的传统,将信息放入表中,称为记帐。会计是在纸上完成的,然后是穿孔卡片,然后是计算机。但是会计已经是现实的减少。会计迫使人们长期遵循它的制度,以至于它已经成为公认的现实。这就是为什么制造会计用的计算机软件相对容易,会计在计算机出现之前就有了它的信息模型。
Given the importance of good accounting systems, and the acceptance you get from any business managers, these systems have become very advanced. The database foundations are now very solid and noone hesitates about keeping vital data in something so trustworthy.
考虑到良好的会计系统的重要性,以及你从任何业务经理那里得到的认可,这些系统已经变得非常先进。数据库基础现在非常坚实,没有人会犹豫是否要将重要数据保存在如此值得信赖的东西中。
I guess that OO must have come along when people have found that other aspects of reality are harder to model than accounting (which is already a model). OO has become a very successful idea, but persistance of OO data is relatively underdeveloped. RDB/Accounting has had easy wins, but OO is a much larger field (basically everything that isn't accounting).
当人们发现现实中的其他方面比会计更难建模时(会计已经是一个模型),我猜想OO一定会出现。OO已经成为一个非常成功的想法,但是OO数据的持久性相对不发达。RDB/Accounting容易获胜,但OO是一个更大的领域(基本上所有的东西都不是Accounting)。
So many of us have wanted to use OO but we still want safe storage of our data. What can be safer than to store our data the same way as the esteemed accounting system does? It is an enticing prospects, but we all run into the same pitfalls. Very few have taken the trouble to think of OO persistence compared to the massive efforts by the RDB industry, who has had the benefit of accounting's tradition and position.
我们中的许多人都想使用OO,但我们仍然希望数据的安全存储。还有什么比像受人尊敬的会计系统那样存储我们的数据更安全的呢?这是一个诱人的前景,但我们都遇到了同样的陷阱。与RDB行业的巨大努力相比,很少有人费心去思考OO持久性,RDB行业得益于会计的传统和地位。
Prevayler and db4o are some suggestions, I'm sure there are others I haven't heard of, but none have seemed to get half the press as, say, hibernation.
普雷维勒(Prevayler)和db4o给出了一些建议,我肯定还有其他一些我没有听说过的建议,但似乎没有一个像冬眠(hibernation)这样得到一半的报道。
Storing your objects in good old files doesn't even seem to be taken seriously for multiuser applications, and especially web applications.
对于多用户应用程序,尤其是web应用程序,将对象存储在良好的旧文件中似乎都不被重视。
In my everyday struggle to close the chasm between OO and RDB I use OO as much as possible but try to keep inheritance to a minimum. I don't often use SPs. I'll use the advanced query stuff only in aspects that look like accounting.
在我努力消除OO和RDB之间的鸿沟的日常工作中,我尽可能多地使用OO,但尽量将继承保持在最低限度。我不经常使用SPs。我将只在类似会计学的方面使用高级查询。
I'll be happily supprised when the chasm is closed for good. I think the solution will come when Oracle launches something like "Oracle Object Instance Base". To really catch on, it will have to have a reassuring name.
当鸿沟永远封闭的时候,我将会很高兴。我认为当Oracle启动“Oracle对象实例库”时,解决方案就会出现。要真正流行起来,它必须有一个让人放心的名字。
#23
1
Not a lot of time at the moment, but just off the top of my head...
现在不是很多时间,但就在我的头顶上……
The entity model lets you give a consistent interface to the database (and other possible systems) even beyond what a stored procedure interface can do. By using enterprise-wide business models you can make sure that all applications affect the data consistently which is a VERY important thing. Otherwise you end up with bad data, which is just plain evil.
实体模型允许您为数据库(以及其他可能的系统)提供一致的接口,甚至超出存储过程接口的功能。通过使用企业范围的业务模型,您可以确保所有应用程序都一致地影响数据,这是非常重要的事情。否则,你就会得到糟糕的数据,这简直就是罪恶。
If you only have one application then you don't really have an "enterprise" system, regardless of how big that application or your data are. In that case you can use an approach similar to what you talk about. Just be aware of the work that will be needed if you decide to grow your systems in the future.
如果您只有一个应用程序,那么无论应用程序或数据有多大,您都没有真正的“企业”系统。在这种情况下,您可以使用类似于您所谈论的方法。如果您决定在未来发展您的系统,请注意需要做的工作。
Here are a few things that you should keep in mind (IMO) though:
以下是一些你应该记住的事情(在我看来):
- Generated SQL code is bad (exceptions to follow). Sorry, I know that a lot of people think that it's a huge time saver, but I've never found a system that could generate more efficient code than what I could write and often the code is just plain horrible. You also often end up generating a ton of SQL code that never gets used. The exception here is very simple patterns, like maybe lookup tables. A lot of people get carried away on it though.
- 生成的SQL代码很糟糕(以下是例外)。对不起,我知道很多人认为这是一个巨大的节省时间的系统,但我从来没有发现一个系统可以产生比我所能写的更有效的代码,而且代码通常是非常糟糕的。您还常常生成大量从未使用过的SQL代码。这里的例外是非常简单的模式,比如查找表。然而,很多人都被它迷住了。
- Entities <> Tables (or even logical data model entities necessarily). A data model often has data rules that should be enforced as closely to the database as possible which can include rules around how table rows relate to each other or other similar rules that are too complex for declarative RI. These should be handled in stored procedures. If all of your stored procedures are simple CRUD procs, you can't do that. On top of that, the CRUD model usually creates performance issues because it doesn't minimize round trips across the network to the database. That's often the biggest bottleneck in an enterprise application.
- 实体<>表(甚至逻辑数据模型实体必须)。数据模型通常有数据规则,这些规则应该尽可能紧密地强制到数据库中,这些规则可以包括关于表行如何相互关联的规则,或者对于声明性RI来说过于复杂的其他类似规则。这些应该在存储过程中处理。如果您的所有存储过程都是简单的CRUD过程,那么您不能这样做。除此之外,CRUD模型通常会产生性能问题,因为它不会最小化跨网络到数据库的往返。这通常是企业应用程序中最大的瓶颈。
#24
1
Sometimes, your application and data layer are not that tightly coupled. For example, you may have a telephone billing application. You later create a separate application which monitors phone usage to a) better advertise to you b) optimise your phone plan.
有时候,应用程序和数据层没有那么紧密地耦合。例如,您可能有一个电话计费应用程序。之后你创建了一个单独的应用程序来监控手机的使用情况a)更好地为你做广告b)优化你的手机计划。
These applications have different concerns and data requirements (even the data is coming out of the same database), they would drive different designs. Your code base can end up an absolute mess (in either application) and a nightmare to maintain if you let the database drive the code.
这些应用程序有不同的关注点和数据需求(即使数据来自同一个数据库),它们将驱动不同的设计。如果让数据库驱动代码,您的代码库可能最终会变得一团糟(在任何一个应用程序中都是如此),而且维护起来会很麻烦。
#25
1
Applications that have domain logic separated from the data storage logic are adaptable to any kind of data source (database or otherwise) or UI (web or windows(or linux etc.)) application.
将域逻辑与数据存储逻辑分离的应用程序适用于任何类型的数据源(数据库或其他)或UI (web或windows(或linux等))应用程序。
Your pretty much stuck in your database, which isn't bad if your with a company who is satisfied with the current database system your using. However, because databases evolve overtime there might be a new database system that is really neat and new that your company wants to use. What if they wanted to switch to a web services method of data access (like Service Orientated architecture sometime does). You might have to port your stored procedures all over the place.
如果你的公司对你使用的当前数据库系统感到满意,那么你的数据库就会陷入困境。然而,由于数据库随着时间的推移不断发展,可能会有一个新的数据库系统,非常干净和新颖,您的公司希望使用它。如果他们想要切换到数据访问的web服务方法(比如某个时候的面向服务的体系结构),会怎么样呢?您可能需要到处移植存储过程。
Also the domain logic abstracts away the UI, which can be more important in large complex systems that have ever evolving UIs (especially when they are constantly searching for more customers).
此外,领域逻辑还抽象出UI,这在曾经发展过UI的大型复杂系统中可能更为重要(特别是当它们不断地搜索更多的客户时)。
Also, while I agree that there is no definitive answer to the question of stored procedures versus domain logic. I'm in the domain logic camp (and I think they are winning over time), because I believe that elaborate stored procedures are harder to maintain than elaborate domain logic. But that's a whole other debate
此外,尽管我同意存储过程与域逻辑之间的关系并没有明确的答案。我在域逻辑阵营(我认为他们会赢得时间),因为我认为复杂的存储过程比复杂的域逻辑更难维护。但这是另一场辩论
#26
0
I think that you are just used to writing a specific kind of application, and solving a certain kind of problem. You seem to be attacking this from a "database first" perspective. There are lots of developers out there where data is persisted to a DB but performance is not a top priority. In lots of cases putting an abstraction over the persistence layer simplifies code greatly and the performance cost is a non-issue.
我认为你只是习惯于写一种特定的应用,并解决某种问题。您似乎是从“数据库优先”的角度来攻击这个问题的。有很多开发人员将数据持久化到数据库中,但是性能并不是他们的首要任务。在许多情况下,将抽象放在持久性层之上可以极大地简化代码,并且性能成本也不是问题。
Whatever you are doing, it's not OOP. It's not wrong, it's just not OOP, and it doesn't make sense to apply your solutions to every othe problem out there.
不管你在做什么,都不是OOP。这并不是错的,它只是没有OOP,并且把你的解决方案应用到每一个问题上是没有意义的。
#27
0
Interesting question. A couple thoughts:
有趣的问题。几个想法:
- How would you unit test if all of your business logic was in your database?
- 如果所有的业务逻辑都在数据库中,那么如何进行单元测试呢?
- Wouldn't changes to your database structure, specifically ones that affect several pages in your app, be a major hassle to change throughout the app?
- 改变你的数据库结构,特别是影响你的应用中的几个页面的结构,会不会成为整个应用中最麻烦的事情?
#28
0
Good Question!
好问题!
One approach I rather like is to create an iterator/generator object that emits instances of objects that are relevant to a specific context. Usually this object wraps some underlying database access stuff, but I don't need to know that when using it.
我比较喜欢的一种方法是创建一个迭代器/生成器对象,该对象发出与特定上下文相关的对象实例。通常这个对象封装了一些底层数据库访问内容,但是我不需要在使用它时知道这些内容。
For example,
例如,
An AnswerIterator object generates AnswerIterator.Answer objects. Under the hood it's iterating over a SQL Statement to fetch all the answers, and another SQL statement to fetch all related comments. But when using the iterator I just use the Answer object that has the minimum properties for this context. With a little bit of skeleton code this becomes almost trivial to do.
AnswerIterator对象生成AnswerIterator。回答对象。在底层,它遍历一个SQL语句以获取所有答案,而另一个SQL语句则获取所有相关的注释。但是在使用迭代器时,我只使用具有此上下文的最小属性的Answer对象。使用一些框架代码,这就变得非常简单。
I've found that this works well when I have a huge dataset to work on, and when done right, it gives me small, transient objects that are relatively easy to test.
我发现,当我有一个庞大的数据集要处理时,它就能很好地工作,如果处理得当,它会给我提供相对容易测试的小的、短暂的对象。
It's basically a thin veneer over the Database Access stuff, but it still gives me the flexibility of abstracting it when I need to.
它基本上只是数据库访问的一种虚饰,但是当我需要时,它仍然为我提供了抽象它的灵活性。
#29
0
The objects in my apps tend to relate one-to-one to the database, but I'm finding using Linq To Sql rather than sprocs makes it much easier writing complicated queries, especially being able to build them up using the deferred execution. e.g. from r in Images.User.Ratings where etc. This saves me trying to work out several join statements in sql, and having Skip & Take for paging also simplifies the code rather than having to embed the row_number & 'over' code.
我的应用程序中的对象倾向于一对一地与数据库相关联,但我发现使用Linq to Sql而不是sprocs更容易编写复杂的查询,特别是能够使用延迟执行构建它们。从图片中的r开始。这使我不必尝试在sql中构造几个连接语句,并且使用Skip & Take进行分页也可以简化代码,而不必嵌入row_number和'over'代码。
#30
0
Why stop at entity objects? If you don't see the value with entity objects in an enterprise level app, then just do your data access in a purely functional/procedural language and wire it up to a UI. Why not just cut out all the OO "fluff"?
为什么要停在实体对象上?如果您在企业级应用程序中没有看到实体对象的值,那么只需使用纯函数/过程性语言进行数据访问,并将其连接到UI。为什么不剪掉所有的OO“fluff”呢?