11

所以,假设我有这个组件的一个实例:

foo.cfc

<cfcomponent>
  <cffunction name="locateMe">
    <cfreturn "I don't know where I live!">
  </cffunction>
</cfcomponent>

而且,另一个组件 fooParent.cfc:

<cfcomponent>
  <cfset this.foo = createObject("component", "foo")>
</cfcomponent>

假设我以几种不同的方式创建“foo”的实例:

<cfset myStruct = {}>
<cfset myStruct.foo = createObject("component", "foo")>

<cfset myFoo = createObject("component", "foo")>

<cfset myFooParent = createObject("component", "fooParent")>

<cfoutput>
#myStruct.foo.locateMe()#<br>
#myFoo.locateMe()#<br>
#myFooParent.foo.locateMe()#<br>
</cfoutput>

正如预期的那样,这输出:

I don't know where I live!
I don't know where I live!
I don't know where I live!

我想知道的是,我可以在 foo.cfc 中做些什么来告诉我一些(任何东西!)关于它被调用的上下文?由于一切最终都存在于(至少)某种范围内,并且所有范围都是一种对象,我的意思是我真的很想从给定的实例化对象中确定包含对象的某种方式。最终,某种构建 foo.cfc 的方式,以便像这样的东西可以作为我的输出,来自我上面的示例片段:

I live within a "class coldfusion.runtime.Struct" instance!
I live within a "class coldfusion.runtime.VariableScope" instance!
I live within a "component cfjunk.fooParent" instance!

其中每个值都可以通过检查传递getMetaData实际包含对象引用的结果来确定。

更新正如 Micah 在评论中所建议的那样,我已经为此添加了“Java”标签,因为我怀疑他可能是正确的,因为解决方案可能在于使用 Java 进行自省。

更新

与其让这个看起来像是纯粹的学术讨论,让我解释一下为什么我需要这个。

我正在使用带有包含的 CFWheels ORM 来获取对我的数据的引用,如下所示:

var user = model("User").findOne(where="id=123", include="AuthSource", returnAs="object");

这将返回给我一个我可以像这样引用的对象:

user.id // property of the "User" model
user.reset() // method on the "User" model
user.AuthSource.id // property of the "AuthSource" model
user.AuthSource.authenticate(password) // method on the "AuthSource" model

现在,在我的“AuthSource.authenticate”方法中,我想知道我包含在其中的“用户”对象。否则,我最终将不得不像这样调用函数,而不是:

user.AuthSource.authenticate(user, password) // note the redundancy in the use of "user"

我应该能够依赖这样一个事实,即我通过 User 对象调用 AuthSource 模型上的方法,并从该方法中实际读取该对象。

4

3 回答 3

4

自从我完成冷融合以来已经很长时间了,所以请原谅我的伪代码,但我认为在这种情况下通常会做的是让父母在实例化孩子时将自己的副本发送给孩子。这在许多 OOP 设计模式中使用,其中两个对象需要以两种方式相互通信,而不仅仅是父级调用子级的方法。

所以你的子类将被定义为这样的:

<cfcomponent>
  <cffunction name="init">
     <cfargument name="parentParam" required="yes" type="object">
     <cfset this.parent = parentParam >
      <cfreturn this> 
   </cffuncton>
  <cffunction name="locateMe">
    <cfreturn "I belong to #this.parent.className# !">
  </cffunction>
 <cffunction name="doOtherStuff">
    <cfreturn "I do stuff with my parent: #this.parent.className# !">
  </cffunction>
</cfcomponent>

然后当你使用它时......

<cfset myParent.child = createObject("component", "Object").init(myParent) />
#myparent.locateMe()#
#myparent.doOtherStuff()#

parentParam 将是名为“init”的构造方法中的必需参数,因此子项始终具有对其父项的引用。然后你的所有方法都可以使用 this.parent 来处理它。在我的代码示例中,我执行 #this.parent.className# 但不知道冷融合对象具有这样的属性。可能您可以使用某种反射或元编程来做同样的事情。

请注意:据我所知,coldfusion 不支持内置的构造函数,所以我向您展示的是该站点的社区标准最佳实践:

http://www.iknowkungfoo.com/blog/index.cfm/2007/8/22/Object-Oriented-Coldfusion--1--Intro-to-Objectcfc

对不起,你在搞勾结……;)

于 2012-02-16T21:21:39.403 回答
0

我已经删除了所有以前的内容,因为它似乎没有帮助。在您后来的评论之后,以下是我认为可能更符合您的目标的建议。

// Object
<cfcomponent displayname="Object">
    <cffunction name="init">
        <cfargument name="username" type="string">
        <cfscript>
            variables.username = arguments.username;
            variables.authSource = CreateObject('component','AuthSource').init();
        </cfscript>
        <cfreturn this>
    </cffunction>
    <cffunction name="authenticate">
        <cfargument name="password" type="string">
        <cfreturn variables.authSource.authenticate(variables.username,arguments.password)>
    </cffunction>
 </cfcomponent>

<cfcomponent displayname="AuthSource">
    <cffunction name="init">
        <cfreturn this>
    </cffunction>
    <cffunction name="authenticate">
        <cfargument name="username" type="string">
        <cfargument name="password" type="string">

            .... DO STUFF ...

        <cfreturn ...>
    </cffunction>
 </cfcomponent>

 <cfscript>
    objUser = CreateObject('component','Object').init('SomeUserName');
    // Authenticate
    objUser.authenticate('SomePassword');
 </cfscript>

这样,AuthSource 不需要知道父对象,但是同时验证的人不需要再次传入用户名。对象(父对象)有一个用于身份验证的包装方法,它添加了用户名。

这有什么进一步的帮助吗?

于 2012-02-17T08:37:51.543 回答
0

我知道这现在不相关,但下一个版本的 CF (Zeus) 具有执行此操作的功能http://blogs.adobe.com/coldfusion/2011/12/19/coldfusion-zeus-potr-callstack/ .

于 2012-02-17T16:36:29.257 回答