允许不同的ColdFusion CFC相互实例的正确方法是什么?

时间:2014-11-07 16:38:20

标签: coldfusion cfc

关于实例CFC的正确方法,我有一个“最佳实践”问题,所有CFC都需要在给定项目中相互交流。

比方说,您有一个Web应用程序,其中包含许多不同的模块:

  • 在线日历
  • 在线商店
  • 博客
  • 文件管理器(上传/下载/处理文件)
  • 用户帐户

这些模块中的每一个都组织得很好,因此与每个模块相关的功能都包含在单独的CFC文件中:

  • Calendar.cfc
  • Store.cfc
  • Blog.cfc
  • Files.cfc
  • Users.cfc

每个CFC都包含适用于该特定模块的功能。例如,Users.cfc包含与开启/关闭用户,更新帐户信息等有关的功能...... 有时,CFC可能需要引用另一个CFC中的函数,例如,如果商店(Store.cfc)需要从客户(Users.cfc)获取信息。但是,我不确定实现这一目标的正确方法。我可以通过几种方式让我的CFC互相参考:

方法1:在CFC中,实例化您需要的其他CFC:

<!--- Store.cfc --->
<cfcomponent>

<!--- instance all the CFC’s we will need here --->
<cfset usersCFC = CreateObject("component","users") />
<cfset filesCFC = CreateObject("component","files") />

<cffunction name="storeAction">

     <cfset var customerInfo = usersCFC.getUser(1) />

这种方法似乎大部分时间都有效,除非某些实例化的CFC也实例化了它们的实例CFC。例如:如果Users.cfc实例Files.cfc和Files.cfc也是Users.cfc实例。我遇到了偶然的可怕的NULL NULL错误,这可能是因为某种类型的无限递归问题。

方法2:在CFC的函数范围内实例化所需的CFC(这似乎可以防止递归问题):

<!--- Store.cfc --->
<cfcomponent>

     <cffunction name="storeAction">

          <!--- create a struct to keep all this function’s variables --->
           <cfset var local = structNew() />

          <!--- instance all the CFC’s we will need here --->
           <cfset local.usersCFC = CreateObject("component","users") />
           <cfset local.filesCFC = CreateObject("component","files") />

          <cfset var customerInfo = local.usersCFC.getUser(1) />

我对这种方法的关注是它在内存和处理效率方面可能效率不高,因为你最终需要为每个需要它的函数多次实例化相同的CFC。然而,它确实通过将CFC隔离到它们各自的函数范围来解决无限递归方法1的问题。

根据我在网上看过的内容以及面向对象编程的文章,我想到的一件事是利用“Base.cfc”,它使用cfcompontent标签的“extends”属性来实例化所有应用程序中的CFC。但是,我之前从未测试过这种类型的设置,而且我不确定这是否是允许我所有CFC相互通信的理想方式,特别是因为我相信使用扩展覆盖功能(如果有的话)共享一个通用的函数名称(例如&#34; init()&#34;)。

<!--- Base.cfc --->
<cfcomponent extends="calendar store blog users files">

什么是正确的&#34;最佳实践&#34;解决这类问题的方法是什么?

2 个答案:

答案 0 :(得分:16)

如果你的每个CFC实例都是单例(即你的应用程序中只需要它的一个实例),那么你肯定想要研究Dependancy Injection。 CF有三种主要的Dependancy Injection框架; ColdSpring,WireBox和DI / 1.

我建议您查看DI / 1或WireBox,因为ColdSpring暂时没有更新。

DI / 1的维基页面在这里: https://github.com/framework-one/di1/wiki/Getting-Started-with-Inject-One

Wirebox wiki页面在这里: http://wiki.coldbox.org/wiki/WireBox.cfm

基本上,这些框架的作用是创建(实例化)您的CFC(bean),然后处理它们彼此之间的依赖关系。因此,当您需要获取实例化的CFC时,它已经连接好并准备好了。

依赖注入有时也称为IoC(控制反转),是许多语言中常用的设计模式。

希望有所帮助,祝你好运!

答案 1 :(得分:1)

如果您的cfcs彼此不相关,则base.cfc概念不适合。继承是针对类具有可以相互继承的常见事物。例如,如果您有User.cfc并且您想要添加名为customer.cfc的新cfc,我将继承User并覆盖某些功能或添加一些而不触及实际的user.cfc。 那么,回到你的问题,由于CFC彼此之间没有关联或相互之间并且为了避免交叉引用,我将创建serviceFactory来保存cfcs的实例,就像这样

    component name="ServiceFactory"
    {
     function init(){
    return this;
     }

     public User function getUserService(){
    return new User();
     }

     public Calendar function getCalendar(){
    return new Calendar(); 
     } 
     }

并通过

引用它
serviceFactory= new ServiceFactory();
userService = serviceFactory.getUserService();

请记住,只有当您有另一种CFC来管理逻辑时,此方法才有效

您可以对所有其他服务执行相同操作。如果您的函数是静态的,您可以将您的服务保存在应用程序范围内并仅实例化一次(如单例)。

您拥有的第三个选项是DI(依赖注入)框架