我在coldfusion组件中使用代理/委托模式,并且从我的角度来看,我得到了意想不到的结果。下面是我的代理组件 - 非常简单,我只是使用我想委托的实际组件初始化CFC,然后将命名函数从该CFC映射到代理函数(以下简化为此示例)< / p>
我创建了一个代理组件,如下所示:
component output="false"{
/** Constructor for proxy - requires an instance of myFusebox **/
public MyFuseboxProxy function init( Required any myFb ){
variables.myFusebox = arguments.myFb;
return this;
}
this.do = variables.proxy;
this.getApplication = variables.proxy;
this.getApplicationData = variables.proxy;
private any function proxy(){
var local.functionName = getFunctionCalledName();
var local.function = variables.myFusebox[local.functionName];
var local.returnVal = local.function( argumentCollection=arguments );
return local.returnVal;
}
}
从我的应用程序中,我调用以下代码:
variables.myFusebox = new ab.MyFuseboxProxy( variables.myFusebox );
variables.myFusebox.getApplicationData().startTime = now();
现在,在上面的场景中,我希望我的代理组件将getApplicationData()函数直接映射到原始的myFusebox组件(通过我的proxy()
函数)。
底层组件中的该函数如下:
<cffunction name="getApplicationData" returntype="struct" access="public" output="false"
hint="I am a convenience method to return a reference to the application data cache.">
<cfreturn getApplication().getApplicationData() />
</cffunction>
该代理一切正常,但是,一旦我在原来的myFusebox中的上述函数中,我得到以下错误:
Message: Variable GETAPPLICATION is undefined.
StackTrace: coldfusion.runtime.UndefinedVariableException: Variable GETAPPLICATION is undefined.
如果我在该函数中转储“this
”,它实际上会转储我的代理对象。
任何人都可以解释这个或我做错了什么吗?我期待一旦函数调用在底层对象中,它就会从那里使用它自己的上下文(我的代理只是真正传递给委托)
答案 0 :(得分:1)
我认为这是关键点:
我期待一旦函数调用在底层内部 对象
你有这个:
private any function proxy(){
var local.functionName = getFunctionCalledName();
var local.function = variables.myFusebox[local.functionName];
var local.returnVal = local.function( argumentCollection=arguments );
return local.returnVal;
}
当你这样做时:
var local.function = variables.myFusebox[local.functionName];
您正在有效地提取local.functionName
的{{1}} out 引用的函数,并将其放入当前函数中variables.myFusebox
实例的上下文中
所以当你这样做时:
MyFuseboxProxy
您没有运行var local.returnVal = local.function( argumentCollection=arguments );
(因此在variables.myFusebox[local.functionName]()
的上下文中),但您正在运行variables.myFusebox
(因此在代理对象的上下文中)。
我没有耐心试图在这里遵循你的逻辑,但我仍然感到惊讶你得到了这个错误。我原以为这会发生:
local.function()
(对local.function
的{{1}}的引用)运行getApplicationData
。variables.myFusebox
实例的上下文中的getApplication()
应该是对getApplication()
的引用。MyFuseboxProxy
将代理函数解析为variables.proxy()
,并将其从variables.proxy()
中拉出,并在getApplication()
实例的上下文中运行。variables.myFusebox
中包含MyFuseboxProxy
函数的代码,所以我不知道接下来会发生什么,但这不是您想要发生的事情。无论如何,关键是 - 我认为 - 不是在getApplication()
内运行函数,而是在variables.myFusebox
实例中运行它们。如果你想进行这种代理(并且暂时忽略了variables.myFusebox
专门用于执行此操作),您仍需要在其原始上下文中调用该函数,而不是在某些新上下文中引用它。
我猜你正在做这一切,因为ColdFusion不喜欢这种语法:
MyFuseboxProxy
它以invoke()
符号表示无效。然而,解决方案不是这样的:
someOutOfContextReference = someObject [someMethodName] result = someOutOfContextReference()
就是这样:
someObject.someInContextReference = someObject [someMethodName] result = someObject.someInContextReference()
看到细微差别?
ColdFusion函数本质上不是闭包,这就是你需要它们以你想要的方式工作。