在请求期间避免重新计算或双重查询的好设计模式是什么?

时间:2016-10-29 11:06:41

标签: php caching design-patterns

使用基于Web的应用程序时,通常不会经常更改的查询结果(或需要大量计算能力的复杂计算结果)会缓存在内存或基于文件的数据存储中。 如果这些结果可能会针对每个请求而更改,但会被应用程序中的许多类消耗,那么在保持SOLID状态的同时,在请求期间缓存此信息的最佳方法是什么?

我看到的最直接的解决方案,以及我现在正在实施的,是为每个这样的实例检查结果是否已经计算/检索,如果没有,计算它并将其存储在变量中

root@labadmin-VirtualBox:/home/labadmin# docker run busybox ping -c 2 192.203.230.10
PING 192.203.230.10 (192.203.230.10): 56 data bytes
64 bytes from 192.203.230.10: seq=0 ttl=56 time=66.724 ms
64 bytes from 192.203.230.10: seq=1 ttl=56 time=54.786 ms
--- 192.203.230.10 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 45.815/56.947/66.724 ms

我用这种方法看到的问题如下:

  • 我必须确保在我需要的任何地方"某些东西",我可以访问同一个对象实例(或者我可以使用更糟糕的静态变量)。这可以通过使用依赖注入并确保每次我从该类请求一个实例时返回相同的实例来实现,但不知何故我无法帮助但感觉我正在应用错误的解决方案。最终我的应用程序将填充特定的实例依赖项。我甚至不确定这是不是坏事,随时纠正我。
  • 我的课程将填充这些基本上做同样事情的if语句。 (检查变量是否已设置,如果没有,则设置它,然后返回所述变量。)Yikes!

我花了一夜寻找更好的解决方案,但除了缓存一个请求的结果(使用装饰器模式保持我的课程干净)之外,我无法想出任何东西,这也感觉不对。

解决这个常见问题的优雅方法是什么,是否有一个我可以实现的已知设计模式?

1 个答案:

答案 0 :(得分:1)

我似乎找到了自己问题的答案。

技术(或模式,如果你想称之为),称为 memoization

Edd Mann的这篇文章提供了一个很好的实际例子,说明如何实现它:

http://eddmann.com/posts/implementing-and-using-memoization-in-php/

此示例中的代码是程序性的,但可以很容易地适用于面向对象的环境。

总而言之,这是一种非常简单的技术,可以在某些情况下提升性能。我当然很高兴我现在有一句话可以用来向别人解释这个! : - )