ActiveRecord比ORM更坏

                   
banq
16-07-30 3 2214 4

ORM已经不好了,ActiveRecord其实比ORM更坏,因为它隐藏对象其实是数据容器这样的事实,如果说ORM是将真正对象变成数据容器,那么ActiveRecord还隐瞒了这样事实,也就是说,如果说ORM做了偷梁换柱的坏事,ActiveRecord不但做了,还隐瞒自己做的坏事。


这是来自
ActiveRecord Is Even Worse Than ORM - DZone Java一文的观点。

作者曾经在2014年提出ORM是反模式的观点,ORM作为一个非常流行的设计模式,是在一个螺丝壳中,把真正对象变成了DTO(数据传输对象),DTO是一种贫血失血的、被动的、非真正的对象(其实是一种数据结构),结果通常是戏剧的,ORM的使用导致整个编程范式从面向对象悄悄偷换回了原来的面向过程编程。在今年的JPoint和JEEConf大会上,作者会继续谈这个问题。

有的人认为ActiveRecord能够解决这个问题,而作者认为只有Repository模式才能解决这个问题。

作者认为ActiveRecord比ORM更坏,ORM是由两个部分组成:session会话和DTO,后者就是所谓的实体,这个实体是没有功能方法的,它们只有从一个session传输到另外一个session的数据,问题是:对象不是数据结构,对象不是数据,对象不只是封装而且会暴露数据,作者连写了五篇文章阐述错误原因。

ActiveRecord没有解决问题,它只是将工程迁移到父对象,所有实体都必须继承它,下面是保存我们的实体到数据库的ORM方式,伪代码:

book.setTitle("Java in a Nutshell");
session.update(book);


下面是ActiveRecord的做法:

book.setTitle("Java in a Nutshell");
book.update();

方法update()是是book的父对象中定义的,这里还是将book作为一个数据容器使用。当被调用时,父对象会从容器book中获得数据,然后更新数据库,这和ORM有什么区别?绝对没有区别,book仍然是一个容器,与SQL无关或任何持久机制无关的数据结果而已。

ActiveRecord相比ORM更坏的是,它隐藏了对象实际是数据容器的事实,一个book伪装成一个正常对象,其他它就是一个被动数据包袱而已。

作者提出会讲SQL的对象才是替代ORM和ActiveRecord的好方式,而会讲SQL的对象实则是Repository模式。

4
clonalman
2016-08-05 14:51

很不幸,ORM和ActiveRecord模式都用过,使用Repository是对的,可以隐藏技术细节,但避免对象成为数据容器,更彻底一点,需要能做到领域模型设计或编码期独立于技术架构,到运行期在加载具体技术框架

如:
order.addOrderLine(orderLine) 或 order.OrderLines.add(orderLine)
orderRepository.add(order);

要优于
orderLine.setOrder(order);
session.save(order);
session.save(orderLine);

要优于
order.create();
orderLine.setOrder(order);
orderLine.create();

按照DDD, repository本身就是领域元素,
后两种,session或order父类都跟领域无关
[该贴被clonalman于2016-08-05 15:22修改过]

banq
2016-08-06 17:16

2016-08-05 14:51 "@clonalman"的内容
orderRepository.add(order); ...


是的,通过对聚合根一次性提交仓储,比破坏聚合封装逐个提交仓储要好得多。至于聚合中对象与数据库数据表之间比较,只保存变化的部分,这种原理类似前端React+虚拟DOM+Redux,期待后端出现类似Redux这样有树形状态更新的数据库。

tecentID6B6DD
2016-09-28 14:26

消息队列 + 流处理实时计算 + nosql存储+sql存贮

kafka + storm+mongodb +mysql +habase

面向对象编程似乎是一种错误的思想.
面向数据编程