我被要求更新一个旧项目。当我进入 cfc 文件时,它有超过 3000 行代码和超过 100 个 cffunctions。我想知道是否可以将 cfc 拆分为多个文件,这些文件的 cffunctions 在逻辑上分组,而无需更改任何其他页面中的代码。
4 回答
遇到类似的问题。我创建了新的 cfcs 并修改了原始函数以调用新 cfcs 中的函数。
例如
<cffunction name="GetStuff" access="remote" returntype="Struct">
<cfreturn createObject("component","myNewCFC").GetStuff(argumentCollection=arguments)/>
</cffunction>
问题意味着有足够的客户端代码使用这个对象,如果对象被分开是很麻烦的,那么在其他地方更改调用是很麻烦的。在这种情况下,将现有对象视为外观- 即为底层类层次结构提供统一接口的对象。
产生层次结构的方法是确定应该一起使用的那些功能。每当我遇到这个问题时,这些函数通常不共享任何状态,而是类似于static
java 方法,但如果有共享状态的函数,它们是这个分组的一个很好的候选者。否则,通常是函数共享相同的输入参数或在名称中倾向于使用相同的措辞(即saveMyData
,loadMyData
等...)。
鉴于该示例,将这些函数复制到一个新的 CFC(例如MyData
)中 - 此时您可以更改函数名称以消除重复或提高其清晰度(例如MyData.load()
)。回到原始对象(即BigCFC
)删除这些函数的实现,而是将调用委托给新创建的 CFC(您可以考虑使新 CFC 成为旧 CFC 组合的一部分)。所以它看起来像这样:
<cffunction name="loadMyData">
<cfargument name="id" type="numeric"/>
<cfreturn variables.myData.load(arguments.id)/>
</cffunction>
variables.myData
作为 CFC 初始化的一部分,将在哪里设置。
采用这种方法意味着您现有的客户端代码不会受到更改的影响,但仍会将所有内容分解为逻辑分组,并将新代码定位为使用更细粒度的 CFC。
重构,重构,重构……
最简单的方法可能是使用cfinclude
注入函数(mixin)
这是一个老问题,我只是偶然发现它,但我想我会在这里插话,因为这是我不得不在很多场合处理的问题。
如果目标只是从代码管理的角度更好地组织事物(而不是说,专门减少每个 CFC 中的方法数量),那么我主张将 CFC 分解为多个 CFM 页面并将它们包含在 CFC 中。从代码管理的角度来看,您可以将多个函数组合到一个命名良好的 CFM 文件中,这一切都变得更容易处理。调用代码保持不变,因为所有函数仍像以前一样在 CFC 中实例化。
我在我的 init 方法中使用了一些代码,它自动包含它在同一文件夹中找到的所有 CFM 文件,并且我在每个文件夹中放置一个 base.cfc 以及分组函数。
例如
<cfscript>
// Set CFC name
Variables.sCFCName = 'appUtils';
// Set folder
Variables.sCFCFolder = GetDirectoryFromPath(GetCurrentTemplatePath());
// Get CFC files
Variables.qCFCFiles = directoryList(Variables.sCFCFolder, true, 'query');
</cfscript>
<!--- Init function --->
<cffunction name="init" access="public" returnType="any" output="false" hint="Constructor">
<cfargument name="DSN" type="string" default="" hint="Datasource" />
<!--- Set DSN --->
<cfset Variables.DSN = Arguments.DSN />
<cfreturn this />
</cffunction>
<!--- Include CFC files --->
<cfoutput query="Variables.qCFCFiles">
<cfif Variables.qCFCFiles.type EQ 'file' AND GetToken(Variables.qCFCFiles.name, 2, '.') EQ 'cfm'>
<cfinclude template="#Variables.qCFCFiles.Name#" />
</cfif>
</cfoutput>