Language agnostic 类应支持接口,但这需要以侵入式方式向类添加逻辑。我们能防止这种情况吗? 我有一个C++应用程序,它从数据库中加载大量数据,然后对数据执行算法(这些算法是CPU和数据密集型的,这是我把所有数据加载到手之前的方法),然后将所有被更改的数据保存回数据库。

Language agnostic 类应支持接口,但这需要以侵入式方式向类添加逻辑。我们能防止这种情况吗? 我有一个C++应用程序,它从数据库中加载大量数据,然后对数据执行算法(这些算法是CPU和数据密集型的,这是我把所有数据加载到手之前的方法),然后将所有被更改的数据保存回数据库。,language-agnostic,orm,design-patterns,separation-of-concerns,Language Agnostic,Orm,Design Patterns,Separation Of Concerns,数据库部分与应用程序的其余部分很好地分开。事实上,应用程序不需要知道数据来自何处。应用程序甚至可以在文件上启动(在这种情况下,一个单独的文件模块将文件加载到应用程序中,最后将所有数据保存回文件) 现在: 数据库层只想将更改的实例保存回数据库(而不是完整的数据),因此它需要知道应用程序更改了什么 另一方面,应用程序不需要知道数据从何而来,因此它不希望感到被迫为其数据的每个实例保持更改状态 为了使我的应用程序及其数据结构尽可能与加载和保存数据的层(可以是数据库,也可以是文件)分开,我不想用启动后

数据库部分与应用程序的其余部分很好地分开。事实上,应用程序不需要知道数据来自何处。应用程序甚至可以在文件上启动(在这种情况下,一个单独的文件模块将文件加载到应用程序中,最后将所有数据保存回文件)

现在:

  • 数据库层只想将更改的实例保存回数据库(而不是完整的数据),因此它需要知道应用程序更改了什么
  • 另一方面,应用程序不需要知道数据从何而来,因此它不希望感到被迫为其数据的每个实例保持更改状态
为了使我的应用程序及其数据结构尽可能与加载和保存数据的层(可以是数据库,也可以是文件)分开,我不想用启动后实例是否发生更改的信息污染应用程序数据结构

但为了使数据库层尽可能高效,它需要一种方法来确定应用程序更改了哪些数据

复制所有数据并在保存时比较数据不是一个选项,因为数据很容易填满数GB的内存

向应用程序数据结构中添加观察者也不是一个选项,因为应用程序算法中的性能非常重要(在所有观察者上循环和调用虚拟函数可能会导致算法中的一个重要性能瓶颈)

还有其他解决办法吗?或者,如果我不想以一种侵入性的方式向我的应用程序类添加逻辑,我是否试图变得过于“模块化”?在这些情况下,务实是否更好


ORM工具如何解决这个问题?它们是否也强制应用程序类保持某种更改状态,还是强制类具有更改观察者?

如果您无法复制数据并进行比较,那么显然您需要某种类型的更改记录。那么,问题是如何更新这些记录

ORM工具可以(如果他们愿意的话)通过在对象中保留标志来解决问题,说明数据是否已更改,如果已更改,则说明什么。听起来好像您正在使原始数据结构可供应用程序使用,而不是使用可以更新标志的整洁封装的变体的对象

因此,ORM通常不需要应用程序跟踪任何细节上的更改。应用程序通常必须说明要保存哪些对象,但ORM随后会确定需要将哪些内容持久化到DB才能做到这一点,并可能在那里应用优化

我想这意味着用你的话来说,ORM在某种松散的意义上为数据结构添加了观察者。它不是一个外部观察者,它是一个知道如何改变自身的对象,但当然,记录什么发生了变化会有一些开销

一种选择是为数据结构提供“慢”的变体(更新标志),以及“快”的直接访问,以及一个标记对象脏的函数。然后,应用程序可以选择是使用允许它忽略问题的可能较慢的变量,还是使用可能较快的变量,要求它在对象启动之前(或者在对象完成之后,可能取决于您对事务和不一致的中间状态所做的操作)将对象标记为脏对象

然后您将有两种基本情况:

  • 我在一组非常大的对象上循环,有条件地对其中的一些对象进行一次更改。为简化应用程序,请使用“慢速”变异器
  • 我对同一个对象做了很多不同的更改,我非常关心访问器的性能。使用“快速”变异体,这可能会直接暴露数据中的某些数组。您对持久性模型有了更多的了解,从而获得了性能
计算机科学中只有两个难题:缓存失效和命名

菲尔·卡尔顿