Ala*_*ano 0 functional-programming scala
比方说,有一个叫做的课RemoteIdGetter.它从服务器返回一个密钥.但是它只向服务器发出请求,如果密钥不够"新鲜",意味着它最后一次被请求,则大于或等于5分钟(300秒).否则,它返回密钥的本地"缓存"值.
我需要在没有(不 var)改变内部状态 RemoteIdGetter或使用纯函数方法的情况下做到这一点.
它可能看起来像这样:
class RemoteIdGetter {
def key = {
if (!needToAskServer) // return the local "cached" value of the key
else makeRequest
}
def makeRequest = // make a request to a remote server to get the key
def time = // current date-time
def lastUpdatedTime = // the last date-time a key has been updated
// (requested from the server)
def needToAskServer = time - lastUpdatedTime >= 300
}
Run Code Online (Sandbox Code Playgroud)
我想知道,这可能吗?我为什么需要它?我只是好奇,如果可能的话.
每次用相同的参数调用它时,纯函数应该返回相同的结果,所以如果你想在没有可变状态的情况下执行此操作,那么RemoteIdGetter每次获得这样的键时都必须生成新的:
case class RemoteIdGetter(cachedKey: Option[KeyType] = None, lastUpdatedTime: Option[DateTime] = None) {
def getKey(time: DateTime) = {
val (key, t) = (for {
k <- cachedKey
lt <- lastUpdatedTime
if (time - lt < cachePeriod)
} yield k -> lt).getOrElse(makeRequest -> time)
key -> RemoteIdGetter(Some(key), Some(t))
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
val (key, newGetted) = oldGetter.getKey(currentDateTime)
Run Code Online (Sandbox Code Playgroud)
您必须RemoteIdGetter每次都使用最新生成的.
或者你可以隐藏可变状态.例如,您可以使用actor:
import akka.actor.ActorDSL._
val a = actor(new Act {
become {
case GetKey => replyAndBecome(sender)
}
def replyAndBecome(sender: ActorRef): {
val key = makeRequest
sender ! key
become getState(key, time)
}
def getState(key: KeyType, lastUpdatedTime: DateTime): Receive = {
case GetKey =>
if (time - lastUpdatedTime < cachePeriod)
sender ! key
else
replyAndBecome(sender)
}
})
Run Code Online (Sandbox Code Playgroud)
没有可见的可变状态(如var,或可变集合),但有一个隐藏的可变状态 - 演员行为.