ORM 与 OO 设计是否会适得其反?
在 OOD 中,对象的设计以其身份和行为为特征。
在我看来,过去使用过 ORM 的主要目的是围绕存储/检索数据的能力。也就是说,ORM对象不是由行为设计的,而是由数据(即数据库表)设计的。案例和要点:许多 ORM 工具都带有指向数据库表并单击对象生成器。
在我看来,如果对象不再以行为为特征,这将使对象的身份和责任变得混乱。随后,如果对象不是由职责定义的,这可能会导致类紧密耦合和总体设计不佳。
此外,我认为在应用程序设置中,您将面临可扩展性问题。
所以,我的问题是,您认为 ORM 是否会对 OO 设计产生反作用?也许根本的问题是它们是否会对应用程序开发产生反作用。
In OOD, design of an object is said to be characterized by its identity and behavior.
Having used ORM's in the past, the primary purpose, in my opinion, revolves around the ability to store/retrieve data. That is to say, ORM objects are not design by behavior, but rather data (i.e. database tables). Case and point: Many ORM tools come with a point-to-a-database-table-and-click-object-generator.
If objects are no longer characterized by behavior this will, in my opinion, muddy the identity and responsibility of the objects. Subsequently, if objects are not defined by a responsibility this could lend a hand to having tightly coupled classes and overall poor design.
Furthermore, I would think that in an application setting, you would be heading towards scalability issues.
So, my question is, do you think that ORM's are counterproductive to OO design? Perhaps the underlying question would be whether or not they are counterproductive to application development.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
良好的数据库设计的要求和良好的面向对象设计的要求之间存在着众所周知但经常被忽视的阻抗不匹配。大多数开发人员(根据我的经验)要么不理解这种阻抗不匹配,要么不在乎。由于更常见的是从数据库开始并从中生成对象(而不是相反),所以,是的,您最终会得到作为持久层非常好的对象,但从面向对象的角度来看并不是最佳的。 (相反,从对象模型生成数据库,让我想把眼睛戳出来。)
为什么从面向对象的角度来看它们不是最佳的?因为 ORM 生成的对象不是业务对象,即使具有部分类等。业务对象模型行为。 ORM 对象模型持久性。我不会花十个段落来争论这种区别。这是 Rocky Lhotka 在他关于 Business Objects 的书中以及他的 CSLA 框架。无论你是否喜欢或使用CSLA,我认为他的论点都是有根据的。
There's a well-known and oft-ignored impedance mismatch between the requirements of good database design and the requirements of good OO design. Most developers (in my experience) either do not understand this impedance mismatch or do not care. Since it's more common to start with the database and generate the objects from it (rather than the reverse), then yes, you'll end up with objects that are great as a persistence layer but sub-optimal from an OO perspective. (The reverse, generating the database from the object model, makes me want to stab my eyes out.)
Why are they sub-optimal from an OO perspective? Because the objects produced by an ORM are not business objects, even with partial classes and the like. Business objects model behavior. ORM objects model persistence. I'm not going to spend ten paragraphs arguing this distinction. It's something Rocky Lhotka has covered quite well in his books on Business Objects and his CSLA framework. Whether or not you like or use CSLA, I think his arguments are solid ones.
所涉及的对象确实具有按照定义的行为进行的数据库读取和写入。除此之外,他们就没有太多其他的了。
现实情况非常简单:面向对象本身并不是目的,它只是达到目的的一种手段——但在某些情况下,它对改善最终结果并没有多大作用。 ORM 的许多用途就是一个很好的例子——它们是 CRUD 应用程序的数千种变体,不需要或不想将任何实际行为附加到它们处理的大多数数据上。
整个应用程序通过不将大量数据“行为”(如果有)编码到应用程序本身的代码中来获得灵活性。相反,他们通常最好将其作为“哑”数据,只需从 UI 传递到数据库,然后返回到报告等。只要稍加小心,这就可以实现相当程度的用户自定义,当您尝试将数据视为真实对象并将真实行为编码到应用程序中时,这几乎是不可能匹配的。
当然,还有另一面:它会使确保数据的完整性或仅适当使用数据变得更加困难 - 我见过代码在计算中意外使用了错误的字段,因此它们我们计算的是办公室数量的平均值,而不是办公室面积的平方英尺数。两者都是用户定义的字段,只是表示内容应该是数字。应用程序无法知道其中一个是否完全合理,而另一个则完全没有意义。
The objects in question do have database reading and writing as defined behavior. They just don't have much other than that.
The reality of the situation is pretty simple: object orientation isn't an end in itself, it's a means to an end -- but in some cases it just doesn't do much to improve the end result. A lot of uses for ORM form a case in point -- they are thousands of variations of CRUD applications that don't need or want to attach any real behavior to most of the data they process.
The application as a whole gains flexibility by not encoding much (if any) of the data's "behavior" into the code of the application itself. Instead, they're often better off with that as "dumb" data, that they simply pass through from UI to database and back out to reports and such. With a bit of care, this can allow a substantial level of user customization that's almost impossible to match when you try to treat the data as real objects with real behavior encoded into the application proper.
Of course, there's another side to that: it can make it substantially more difficult to ensure the integrity of the data or that the data is only used appropriately -- I've seen code that accidentally used the wrong field in a calculation, so they were averaging the office numbers instead of office sizes in square feet. Both were user-defined fields that just said the contents should be numeric. The application had no way to know that one made perfect sense, and the other didn't at all.
是的,但是有相同的(如果不是更多的话)或 ORM 解决方案基于您的对象并生成数据库表。
如果您从数据开始,然后强制自动生成的对象具有对象行为,是的,您可能会感到困惑......但是如果您从对象开始并生成数据库作为辅助层,您最终会得到一些东西即使数据库可能没有达到应有的优化程度,也更有用。
如果您正在寻找不使用 ORM 的借口,请不要使用它。我个人发现它为我节省了数千行代码来完成 ORM 做得很好的琐碎事情。
Yes but there are equal, if not greater numbers or ORM solutions that base themselves off your objects and generate your database tables.
If you start with data and then tramp down forcing auto-generated objects to have object behaviours, yes, you might get confused... But if you start with the object and generate the database as a secondary layer, you end up with something a lot more usable, even if the database isn't perhaps as optimised as it could be.
If you're looking for an excuse not to use ORM, don't use it. I personally find it saves me thousands of lines of code doing trivial things that the ORM does just great.
我不认为 ORM 会对 OO 设计产生反作用,除非你想坚持持久性是行为的一个组成部分。
我将持久性与商业行为分开。您当然可以自由地将业务行为添加到 ORM 为您生成的任何对象中。
I don't believe ORM are counterproductive to OO design, unless you want to insist that persistence is an integral part of behavior.
I'd separate persistence from business behavior. You're certainly free to add busines behavior to any object that an ORM generates for you.
我还见过 ORM 系统,它们倾向于从 OO 模型出发并生成数据库。
如果有的话,我会说 ORM 更偏向于生成良好的 OO 代码,而不是生成良好的数据库代码。
理想情况下,成功的 ORM 连接了两个世界,从业务领域问题解决和实现的角度来看,您的应用程序代码将非常出色,而从规范化、性能和 ETL/报告/复制等角度来看,您的数据库代码和模型将非常出色。
I've also seen ORM systems which tend to go from the OO model and generate the database.
If anything, I would say ORMs are more biased towards producing good OO code than they are to producing good database code.
Ideally, a successful ORM bridges the two worlds and your application code would be great from a business domain problem-solving and implementation perspective and your database code and model would be great from a normalization, performance and ETL/reporting/replication whatever perspective.
在将数据与行为分开的系统上,这绝对会适得其反。
Orm 系统倾向于分析现有的数据库表,以您的语言创建愚蠢的“对象”。这些东西不是真正的对象,因为它们不包含业务行为,但由于人们拥有这些结构,他们往往想要使用它们。
Ruby on Rails(Active Record)实际上将您的数据绑定到“Live”类——这要好得多。
我从未见过一个我真正喜欢的系统——ActiveRecord 很接近,但它做出了一些我不太满意的红宝石假设——最大的问题是提供公共设置器和设置器。默认情况下吸气剂。
但总而言之,我见过很多优秀的 OO 程序员因为 ORM 写出了搞砸的代码。
On systems where it separates your data from behavior it's absolutely counterproductive.
Orm systems tend to analyze existing database tables to create stupid "Objects" in your language. These things are not true objects because they do not contain business behavior, but since people have these structures, they tend to want to use them.
Ruby on Rails (Active Record) actually binds your data to a "Live" class--this is much better.
I've never seen a system I really liked--ActiveRecord is close but it makes a few rubiesque assumptions that I'm not quite comfortable with--the biggest being supplying public setters & getters by default.
But to sum up--I've seen a lot of good OO programmers write screwed up code because of ORM.
与大多数此类问题一样,这取决于您的使用情况。
使用 ORM 工具的主要方法是:
如果从头开始第三种方法是从对象模型设计数据。 (如果可能的话最好)
所以,是的,如果您通过数据表定义对象并在整个代码中使用它,您将不会使用 OOD 并引入非常糟糕的设计和维护问题。
但是,如果您仅使用 ORM 对象作为数据访问工具(替代 ADO),那么您可以自由地将良好的 OOD 和 ORM 一起使用。当然,构建解释层需要更多代码,但可以实现更好的实践,与旧的 ADO 代码相比,所需的代码并不多。
As with most questions of this type, it depends on your usage.
The main ways to use ORM tools are:
If starting from scratch a 3rd method is to design data from your object model. (Best if possible)
So yes, if you define the object by the data tables and use that throughout your code you will not be using OOD and introducing very poor design and maintenance issues.
But if you only use the ORM objects as a data access tool (replacing ADO) then you are free to use good OOD and ORM together. Sure, more code is required to build the interpretation layer, but enables much better practices, with not much more code required than old ADO code.
我从 C# 的角度回答这个问题,因为这是我大部分开发的地方......
我明白你的观点,但我认为通过创建部分类的能力,你仍然可以创建具有你喜欢的任何行为的对象并且仍然获得 OR/M 为数据检索带来的强大功能。
I'm answering this from a C# perspective, since that is where I do the majority of my development....
I see your point, but I think with the ability to create partial classes you can still create objects with any behavior you like and still get the power that an OR/M brings to the table for data retrieval.
从我对 ORM 的了解来看,它们并不违背 OO 原则——事实上,它们相当正交。 (对于信息 - ORM 技术相当新,从 Java 的角度来看)
我的推理是,ORM 可以帮助您将类的数据成员存储到持久存储中,而无需耦合到该存储并自己编写代码。您仍然决定数据成员并编写类的行为。
我猜你可以滥用 ORM 来破坏 OO 原则,但你可以用任何东西做到这一点。您可以使用工具从预先存在的表创建骨架数据类,但您仍然可以创建方法等。
From what I've seen of ORMs they do not go against OO principles - fairly orthogonal to them in fact. (for info - pretty new to ORM technology, Java perspective)
My reasoning is that ORMs help you store the data members of a class to a persistent store without having to couple to that store and write that code yourself. You still decide on the data members and write the behaviours of a class.
I guess you could abuse ORMs to break OO principles, but then you can do that with anything. You might use tooling to create skeletal data classes from a pre-existing table, but you would still create methods etc.