您将如何在 Scala 中实现缓存方面

Posted

技术标签:

【中文标题】您将如何在 Scala 中实现缓存方面【英文标题】:How would you implement a caching aspect in Scala 【发布时间】:2014-05-07 10:16:20 【问题描述】:

头脑风暴:我正在开发一个 Scala 项目,我们在该项目中进行服务调用,并且需要使用 memcache 缓存返回值。我正在开发一个 Python 项目,used decorators 来注释应该缓存其返回值的函数。我正在 Scala 中寻找一种类似的方式来向函数添加缓存方面。

假设我有这个功能def callingService(arg1: String, arg2: Int): String我想要

根据函数名和参数计算缓存键 如果缓存不包含密钥,则执行服务调用 将返回值序列化并存入缓存 否则反序列化缓存值并返回

任何调用 callingService 的代码都不应该知道缓存。 callService 的实现应该只是调用服务 X 并返回一个 String 值,而不是处理缓存的东西。

【问题讨论】:

【参考方案1】:

我更喜欢 Stackable Trait Pattern 和 Cake Pattern:

class Service 
  def callingService(arg1: String, arg2: Int): String = "ok"


trait Memo[K, V] 
  def cache(k: K)(v : => V): V


trait ServiceCache extends Service 
  self : Memo[(String, Int), String] =>

  abstract override def callingService(arg1: String, arg2: Int): String =
    cache((arg1, arg2))  super.callingService(arg1, arg2) 


trait MapCache[K, V] extends Memo[K, V] 
  private val _cache = new collection.mutable.HashMap[K, V]
  def cache(k: K)(v : => V): V = _cache.getOrElseUpdate(k, v)

使用示例:

val service = new Service with ServiceCache with MapCache[(String, Int), String]

当然,您可以实施自己的缓存策略并在创建服务时与之混合

【讨论】:

请注意,蛋糕模式可能会引入过多的样板,最终可能会成为难以维护的模式之一。我最近遇到了类似的情况,最终不得不摆脱蛋糕图案。可能是 Reader monad 可以是更好的选择或隐含的。奥德斯基在尝试其他替代方案后宣布隐含是他的选择。检查这个:groups.google.com/forum/#!msg/scala-user/n50RW4gQBS4/…【参考方案2】:

我不知道在 Scala 中自动执行此操作的方法。我想你会自己做。

您希望任何调用代码都知道缓存。我认为做到这一点的唯一方法是在函数本身内部拥有缓存机制。

为什么不使用闭包:

val cachedFunc = 
  val cache = mutable.Map[Int, Double]()

  def internalFunc(y: Int) : Double = Math.sqrt(y);

  (y: Int) => 
    if (cache.keySet.contains(y))
      cache(y)
    else
    
      val result = internalFunc(y);
      cache += y -> result;
      result
    
  

现在你可以:

cachedFunc(200)

【讨论】:

【参考方案3】:

scalaz 提供了一个不错的缓存实现:http://eed3si9n.com/learning-scalaz-day16

【讨论】:

以上是关于您将如何在 Scala 中实现缓存方面的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Scala 中实现 DAO?

如何在 Scala 中实现 Kafka Consumer

如何在 Scala 中实现真正的 Singleton

您将如何在 C# 中实现“特征”设计模式?

您将如何在 asp.net mvc 中实现面包屑助手?

如何在 spark scala 中实现 uniqueConcatenate、uniqueCount [关闭]