Design patterns 在应用程序内推送数据更改与拉取数据更改

Design patterns 在应用程序内推送数据更改与拉取数据更改,design-patterns,language-agnostic,architecture,Design Patterns,Language Agnostic,Architecture,假设您有一个由两层组成的应用程序: A:存储从数据库或文件加载的所有数据的数据层 B:一个以良好的用户界面显示数据的层,例如图形报告 现在,A层中的数据发生了更改。我们有两种方法来确保B层中的报告得到正确更新 第一种方法是推送方法。层A通过观察者通知层B,以便层B可以更新其报告 推送方式有几个缺点: 如果数据多次更改(例如,在加载过程中或在更改大量数据的算法中),将多次执行观察器。这可以通过引入一种缓冲来解决(防止在您仍在更改时调用观察者),但这可能非常棘手,并且通常会忘记进行正确的缓冲调

假设您有一个由两层组成的应用程序:

  • A:存储从数据库或文件加载的所有数据的数据层
  • B:一个以良好的用户界面显示数据的层,例如图形报告
现在,A层中的数据发生了更改。我们有两种方法来确保B层中的报告得到正确更新

第一种方法是推送方法。层A通过观察者通知层B,以便层B可以更新其报告

推送方式有几个缺点:

  • 如果数据多次更改(例如,在加载过程中或在更改大量数据的算法中),将多次执行观察器。这可以通过引入一种缓冲来解决(防止在您仍在更改时调用观察者),但这可能非常棘手,并且通常会忘记进行正确的缓冲调用
  • 如果更改了大量数据,观察者调用可能会导致应用程序无法接受的开销
另一种方法是拉动方法。层A只记得更改了哪些数据,不发送任何通知(层A标记为脏)。在用户执行操作(可能运行算法或加载文件或其他内容)之后,我们检查所有用户界面组件,并要求它们进行自我更新。 在这种情况下,要求层B进行自我更新。首先,它将检查其底层(层A)是否脏。如果是,它将获得更改并自行更新。如果A层不是脏的,报告就知道它与此无关

最佳解决方案取决于具体情况。在我的情况下,推式方法似乎要好得多

如果我们有两个以上的层,情况会变得更加困难。假设我们有以下4层:

  • A:存储从数据库或文件加载的所有数据的数据层
  • B:使用数据层(层A)的层,例如使用复杂的过滤功能过滤A中的数据
  • C:使用B层的层,例如,将B层的数据聚合成更小的信息片段
  • D:解释C层结果并以良好的图形方式向用户展示的报告
在这种情况下,推动更改几乎肯定会带来更高的开销

另一方面,拉动更改需要:

  • D层必须给C层打电话询问它是否脏
  • C层必须给B层打电话询问它是否脏
  • B层必须给A层打电话询问它是否脏
如果没有任何更改,那么在您知道实际上没有任何更改并且您不必执行任何操作之前要执行的调用数量相当大。似乎我们试图通过不使用PUSH来避免的性能开销现在又回到了PULL方法中,因为有很多调用询问是否有不干净的东西


有没有模式可以以一种好的、高性能(低开销)的方式解决此类问题?

没有。没有免费午餐,就没有银弹。这都要归功于精心的设计。你已经介绍了很多常见的技术,它们需要小心地应用,避免假设

我对你的两项陈述提出质疑:

您的意思是推送通知的控制非常困难。我本以为在很多情况下,你会有一个主计算引擎,它可以获取数据并进行计算。引擎肯定会在某个点停止,并在该点发送“New Data Ready”(新数据准备就绪)事件,该事件可以包含关于所更改内容的更细粒度信息

你说打4个层间电话太贵了。其依据是什么?和什么相比?如果你关心多因子(10d实例)调用(5c实例)调用(2b实例)调用(1a实例),那么我们肯定会优化吗?每个级别都可以说“如果我正在打电话或最近听到了答案,无需再打电话”


当我们考虑这些层的缩放效果时,一些便宜的查询可能不会太大。

< P>通过数据管理器进行推送,并压缩发生在小于N纳秒的变化。 数据管理器实现发布-订阅

这意味着数据生产者只依赖于数据管理器,而数据消费者只获取数据

(消费者的依赖关系发生逆转。)

这使得所有的数据流管道在您的glue代码中都是显式的。 订阅可以提前设置,因此用户不需要知道它是如何工作的

数据管理器可以使用自己的线程调用订户通知,这将生产者与消费者巧妙地分离。
您可以轻松压缩更改,因为数据管理器只使用1个线程进行通知,它可以通过计时器“通知”,当它醒来时,它只看到最新状态。

我没有几个实例;我有数百万个例子。但是你的回答让我意识到一些重要的事情。推送更改通常在实例级别上执行(每个实例更改可能会向前推送更改),而拉送更改则在层级别上执行(因为无论实例数量多少,每个层只需拉一次)。这意味着拉可能比推快得多(至少在我的例子中是这样)。谢谢你的提示。我所说的实例指的是报告过程、Ds,而不是数据项的数量。你没有一百万个D,是吗?如果是的话,我会很感动的。