1

我在冷融合组件中使用代理/委托模式,并且得到了意想不到的结果(从我的角度来看)。下面是我的代理组件——它非常简单,我只是用我想要委托给的实际组件来初始化 CFC,然后将命名函数从该 CFC 映射到代理函数(下面为本示例进行了简化)

我创建了一个代理组件,如下所示:

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在该函数中转储“”,它实际上会转储我的代理对象。

谁能解释这个或我做错了什么?我期待一旦函数调用在底层对象内部,它就会从那里使用自己的上下文(我的代理只是真正传递给委托)

4

1 回答 1

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];

您正在有效地将 out of引用的函数local.functionName 拉出variables.myFusebox,并将其放入 MyFuseboxProxy实例上下文中的当前函数中。

所以当你这样做时:

var local.returnVal = local.function( argumentCollection=arguments );

您没有在运行variables.myFusebox[local.functionName]()(因此在 的上下文中variables.myFusebox),但您正在运行local.function()(因此在您的代理对象的上下文中)。

我没有耐心在这里尝试遵循您的逻辑,但是我仍然很惊讶您收到该错误。我本来预计会发生这种情况:

  1. local.functiongetApplicationData(对from的引用variables.myFusebox)运行getApplication()
  2. getApplication()MyFuseboxProxy实例的上下文中应该是对variables.proxy().
  3. variables.proxy()将代理函数解析为getApplication(),并将其拉出,并在您的实例variables.myFusebox的上下文中运行它。MyFuseboxProxy
  4. 您没有包含getApplication()from 函数的代码variables.myFusebox,所以我不知道接下来会发生什么,但这不是您想要发生的。

无论如何,关键是 - 我认为 - 你不是在里面运行函数variables.myFusebox,而是在你的MyFuseboxProxy实例中运行它们。如果你想做这种代理(暂时忽略你invoke()专门为此做的事情),你仍然需要在它的原始上下文中调用函数,而不是在一些新的上下文中引用它。

我猜你正在做这一切,因为 ColdFusion 不喜欢这种语法:

someObject[someMethodName]()

它对[]()符号犹豫不决。然而解决方案不是这样的:

someOutOfContextReference = someObject[someMethodName] 结果 = someOutOfContextReference()

是这样的:

someObject.someInContextReference = someObject[someMethodName] 结果 = someObject.someInContextReference()

看到细微的差别了吗?

ColdFusion 函数本质上不是闭包,这是您需要它们以您想要的方式工作的方式。

于 2013-07-02T21:27:58.177 回答