के साथ कैशिंग को कार्यान्वित करने के लिए मैंने फ़ंक्शनल और प्रतिक्रियाशील मॉडलिंग पुस्तक से डिज़ाइन सिद्धांत का पालन किया है।क्लेस्ली
तो सभी सेवा विधियां Kleisli
वापस आती हैं।
सवाल यह है कि मैं इन सेवाओं पर अद्यतन करने योग्य कैश कैसे जोड़ सकता हूं।
मेरा वर्तमान कार्यान्वयन यहां है, क्या एक बेहतर तरीका है (मौजूदा संयोजक, अधिक कार्यात्मक दृष्टिकोण, ...)?
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scalaz.Kleisli
trait Repository {
def all : Future[Seq[String]]
def replaceAll(l: Seq[String]) : Future[Unit]
}
trait Service {
def all = Kleisli[Future, Repository, Seq[String]] { _.all }
def replaceAll(l: Seq[String]) = Kleisli[Future, Repository, Unit] { _.replaceAll(l) }
}
trait CacheService extends Service {
var cache : Seq[String] = Seq.empty[String]
override def all = Kleisli[Future, Repository, Seq[String]] { repo: Repository =>
if (cache.isEmpty) {
val fcache = repo.all
fcache.foreach(cache = _)
fcache
}
else
Future.successful(cache)
}
override def replaceAll(l: Seq[String]) = Kleisli[Future, Repository, Unit] { repo: Repository =>
cache = l
repo.replaceAll(l)
}
}
object CacheTest extends App {
val repo = new Repository {
override def replaceAll(l: Seq[String]): Future[Unit] = Future.successful()
override def all: Future[Seq[String]] = Future.successful(Seq("1","2","3"))
}
val service = new CacheService {}
println(Await.result(service.all(repo), Duration.Inf))
Await.result(service.replaceAll(List("a"))(repo), Duration.Inf)
println(Await.result(service.all(repo), Duration.Inf))
}
[अद्यतन] @timotyperigo की टिप्पणी के बारे में, मैं भंडार के स्तर
class CachedTipRepository(val self:TipRepository) extends TipRepository {
var cache: Seq[Tip] = Seq.empty[Tip]
override def all: Future[Seq[Tip]] = …
override def replace(tips: String): Unit = …
}
पर कैशिंग को लागू किया है मैं अभी भी डिजाइन में सुधार करने के प्रतिक्रिया के लिए इच्छुक हूँ।
बस एक विचार ... ऐसा लगता है कि वास्तव में कैशिंग जैसी कुछ डोमेन व्यवहार नहीं है (यानी, कुछ ऐसा जो चाहिए अपनी सेवा का हिस्सा बनें), लेकिन शायद रिपोजिटरी कार्यान्वयन की एक संपत्ति। आपकी सेवा में केवल आवश्यक व्यवहार करने के लिए आवश्यक क्रियाएं होंगी, लेकिन (यदि आप चाहें) तो आपका आवेदन कैशिंग और गैर-कैशिंग रेपॉजिटरीज़ के बीच चयन कर सकता है। भंडार कार्यान्वयन के भीतर, आप कैशिंग के लिए एक अधिक कार्यात्मक दृष्टिकोण के लिए राज्य मोनैड की तरह कुछ उपयोग कर सकते हैं। –