假设您有一个由两层组成的应用程序:
现在,数据在A层中发生了变化。我们有2种方法可以确保B层的报告得到正确更新。
第一种方法是PUSH方法。 A层通过观察者通知B层,因此B层可以更新其报告。
PUSH方法有几个缺点:
另一种方法是PULL方法。 A层只记得哪些数据已更改,并且没有发出通知(A层标记为脏)。在用户执行的操作(可能正在运行算法或加载文件或其他内容)之后,我们检查所有用户界面组件,并要求他们自行更新。 在这种情况下,要求层B自我更新。首先,它将检查它的任何底层(A层)是否脏。如果是,它将获得更改并自行更新。如果A层不脏,报告就知道它没什么可做的。
最佳解决方案取决于具体情况。在我的情况下,PUSH方法看起来好多了。
如果我们有超过2层,情况会变得更加困难。假设我们有以下4层:
在这种情况下,推动这些变化几乎肯定会带来更高的开销。
另一方面,拉出更改需要:
如果在你知道实际上什么都没有改变而且你不需要做任何事情之前没有改变任何改变执行的调用量就相当大了。看起来我们试图通过不使用PUSH来避免的性能开销现在又回到了PULL方法中使用,因为有许多调用询问是否有任何问题。
是否存在以良好且高性能(低开销)方式解决此类问题的模式?
答案 0 :(得分:3)
没有。没有免费的午餐,没有银弹。这一切都归功于精心设计。你已经涵盖了巧妙应用它们的常用技术,需要谨慎和避免假设。
我查询了你的两个陈述:
你暗示控制PUSH通知非常困难。我原本预计在很多情况下你会有一个主计算引擎,它可以抓取数据并进行计算。引擎肯定会在某个时刻停止,此时它可以发送“新数据就绪”事件,该事件可以包含有关更改内容的更细粒度的信息。
你说4次层间通话太贵了。那是什么基础?与什么相比?如果您担心多重因素(10 D实例)调用(5个C实例)调用(2个B实例)调用(1个实例),那么A会被100个调用命中,那么我们肯定会优化吗?每个级别都可以说“如果我正在呼叫或者我最近听到了答案,则无需再次拨打电话”。
当我们考虑图层的缩放优势时,一些便宜的查询可能不会过多。
答案 1 :(得分:0)
通过数据管理器推送,并压缩在不到n纳秒内发生的更改。 数据管理器实现了发布 - 订阅。
这些平均数据生成者只依赖于数据管理器,数据使用者只能获取数据。
(消费者有依赖性逆转。)
这使得胶水代码中的所有数据流管道都清晰可见。 订阅可以提前设置,因此conusmers不需要知道它是如何工作的。
数据管理员可以使用自己的线程来调用订阅者通知,从而将生产者与消费者完美地分离。 您可以轻松压缩更改,因为数据管理器仅使用1个线程进行通知,可以通过计时器“通知”,当它被唤醒时,它只能看到最新的状态。