我理解您希望避免传入要缓存到的实际范围结构,但您的选择是有限的。首先想到的是传递您希望存储缓存的范围的名称(字符串)并进行评估。就其性质而言,评估效率低下,应该避免。也就是说,我很好奇它是如何实现的。我没有你的代码,所以我在这里做了一个非常简单的“存储”抽象 CFC(跳过缓存,因为它与我想要测试的内容无关):
缓存.cfc:
<cfcomponent>
<cfset variables.cacheScope = "session" /><!--- default to session --->
<cfset variables.cache = ""/>
<cfscript>
function init(scope){
variables.cacheScope = arguments.scope;
return this;
}
function cacheWrite(key, value){
structInsert(evaluate(variables.cacheScope),arguments.key,arguments.value,true);
return this;
}
function cacheRead(key){
if (not structKeyExists(evaluate(variables.cacheScope), arguments.key)){
return "";
}else{
variables.cache = evaluate(variables.cacheScope);
return variables.cache[arguments.key];
}
}
</cfscript>
</cfcomponent>
并对其进行测试:
<!--- clear out any existing session vars --->
<cfset structClear(session)/>
<!--- show empty session struct --->
<cfdump var="#session#" label="session vars">
<!--- create storage object --->
<cfset cacher = createObject("component", "cache").init("session")/>
<!--- store a value --->
<cfset cacher.cacheWrite("foo", "bar")/>
<!--- read stored value --->
<cfset rtn = cacher.cacheRead("foo")/>
<!--- show values --->
<cfdump var="#rtn#">
<cfdump var="#session#" label="session vars">
题外话:我喜欢编写我的 setter 函数来返回“this”[如上所示],这样我就可以像 jQuery 一样链接方法调用。部分视图可以很容易地写成:
<cfset rtn = createObject("component", "cache")
.init("session")
.cacheWrite("foo", "bar")
.cacheRead("foo")/>
有趣的是,这是可能的,但由于 Evaluate 的间接成本,我可能不会在生产中使用它。我想说这是传递您要缓存到的范围的足够充分的理由。
如果您仍然对此感到困扰(也许是对的?),您可以创建另一个 CFC,从所需范围抽象读取和写入,并将其传递到您的缓存 CFC 作为存储位置(非常适合ColdSpring的任务) ,这样,如果您决定将缓存移动到另一个范围,则不必编辑 300 个页面,全部使用将“会话”传递给 init 的缓存 CFC,而是可以编辑 1 个 CFC 或您的 ColdSpring 配置。
但是,当您具有请求范围时,我不完全确定为什么要进行单请求缓存。如果您正在寻找一种为当前请求缓存某些内容并在不久之后将其终止的方法,那么请求范围可能就是您想要的。当跨越多个请求时,缓存通常更有价值。