这篇专题首先是出现在 Ben Forta 的专栏 (ColdFusion Developer's Journal* 里面), 这是经过 ColdFusion Developer's Journal 的许可而转载的。
Macromedia 公司的 ColdFusion MX 有许多新技术, 其中一项功能我觉得各位在日常开发里将常会(甚至是必须)用到, 即 ColdFusion 的组件功能。在接下来的几个月我将会深入讲解 ColdFusion 的组件概念, 以及它的使用技巧。
下载范例程序:
由于本文多处与范例程序相关, 建议下载范例程序, 并用您习惯的开发工具打开。
了解CFC之前最重要的是关于对象的概念。
首先必须知道—CFML 不是面向对象语言, 而且 CFC 并未提供所有面向对象程序语言应有的功能。这不是一件坏事, 因为面向对象语言牵涉到许多外来属性, 语法规则上也过于复杂。但对于使用 CFML 这类快速开发语言的开发人员来说, 没道理不能使用面向对象技术, 这就有了 CFC, 它的诞生可以说是为了简化一些程序设计上对 OOP 的需求。
为了简单易用, 也为了避开纯粹面向对象程序中遇到的一些恼人的问题, CFC 中的对象只是简单的做到在程序中重复使用。就像黑匣子一样, 不管您如何设计它, 别人都不需要知道您是怎么设计它的, 但是可以为人所用。听起来有点像自定义标签, 的确CFC与自定义标签有许多类似之处, 但 CFC 的作用比自定义标签来的强大。例如说它们常常不仅包含标签与函数, 还可以包含任何数据, 允许完整地封装任何数据和程序。对象通常具有多个方法 (method), 它提供自动进行初始化的机制, 而且不需要入口 (例如 Java 里的 main()), 对象可以被转接及修改, 现有的程序代码都可以用继承的方式自动结合, 不必真正动手去更改源代码。
如果听起来有些深奥的话, 那么下面的例子可以帮助您理解。
几乎所有的 ColdFusion 开发人员都有处理用户的经验, 实际中经常遇到的有以下几种:
<CFQUERY7> 去验证用户提供的用户名和密码。在做这些事情的时候, 在您的代码中有多少地方是用来查阅到用户当前状态, 有多少代码是重复 (或复制并粘贴) 的?当表结构发生改变了, 您的代码有多少受到影响需要修改呢?如果是您的用户数据库将被 LDAP 服务器取代, 或者需要加入新用户规则和新的用户等级?对于那些并不从事程序设计的网页设计师们, 需要对用户管理功能了解到什么程度, 才能利用现有的程序轻松地做出用户欢迎界面?
在对象的世界里, 您可以编写截然不同的程序, 您可以创建用户对象—一个“黑匣子”, 把所有功能都放在里面, 包含任何跟使用者相关数据库 (或 LDAP) 的存取动作。当使用者在操作时, 您需要创建一个关于这个用户对象的实例, 可能要指定这个用户的 ID, 这样您就可以使用这个对象的所有方法, 例如常见的:
或是其它特殊的方法, 例如:
设计的概念是: 所有的外部请求都放在对象中处理。您不用直接去对用户表进行操作, 实际上您也没有必要知道数据存放在哪里, 重要的是您只要知道如何调用您需要的对象的方法, 剩余的事情全部交给对象去完成。
以上就是有关 CFC 功能的举例。
现在您应该知道什么是 CFC 了, 让我们一起来看看他们是怎么创建的。首先请确认 ColdFusion 的服务运行正常。建立 CFC 的步骤充分表现了 ColdFusion 的宗旨: 非常容易!只要两个步骤就可以完成:
这四个新标签是:
<CFCOMPONENT>: 定义新组件<CFFUNCTION>: 在组件中定义方法<CFARGUMENT>: 定义传入方法的参数变量<CFRETURN>: 从方法中返回结果尽管这些功能类似在 CFMX 中创建自定义标签与自定义函数, 但它不同于自定义标签与自定义函数, 在组件中您可以很自由地使用任何标签、方法、系统标签、组件…等。
Listing 1 (看范例程序代码) 有一些简单的例子让大家更了解 CFC, 这是一个验证浏览器用的 CFC, 用于辨识使用者的浏览器种类。
这个文件的名字是 browser.cfc, 它就是一个 CFC。在 CFC 组件里, 所有代码都是被包含在 <CFCOMPONENT> 和 </CFCOMPONENT> 之中。这个组件自己本身有一个单独的函数isIE(), 是使用 <CFFUNCTION> 来命名和定义的。在这个函数中有一个变量被定义为result, 如果浏览器的标识包含了Microsoft Internet Explorer的标识符, 这个变量就会被设定为“YES”, 并通过 <CFRETURN> 返回 result 这个变量。
这不是完整的例子(虽然它可以使用), 但这是好的开始。
要如何使用这个组件呢?先保存它为 browser.cfc, 在相同的目录下创建一个 test.cfm 的文件, 包含以下代码:
<!--- 呼叫 browser CFC --->
<CFINVOKE COMPONENT="browser"
METHOD="IsIE"
RETURNVARIABLE="result_ie">
<!--- 显示到画面上 --->
<CFOUTPUT>
Your browser is:<BR>
IE: #YesNoFormat(result_ie)#<BR>
</CFOUTPUT>
<CFINVOKE> 是 CFMX 的新标签, 它的作用就是用来执行 CFC 里面的方法 (method), 并取得传回的数据。RETURNVARIABLE 代表得到回传的数据时, 要将它放到哪个变量里面。
您可以尝试执行这段程序代码, 当您在 IE 与其它浏览器中执行它的时候, 会得到不同的结果。
现在您应该熟悉 CFC 工作的方式了, 接着看 Listing 2, 这是完整版的 browser.cfc。这个版本的 cfc 有些复杂, 其中的 <CFCOMPONENTS> 包含了四个方法:
您可以注意到我们在每个函数中添加了两个新属性。
RETURNTYPE: 指定返回数据的类型, 用来验证返回的数据(如果是错误的类型, 将提示错误)。HINT: 当这个 CFC 自动产生说明文件的时候, 会用这个字符串来叙述这个函数的功能。(等一下会解释得更详细)在简单版的 browser.cfc 中, 代码主要是去验证 CGI 变量 HTTP_ USER_ AGENT 以便判断是否为该浏览器, 但这并不是很好的做法, 因为这些函数应该要能验证任何传入的字符串, 而不是仅仅验证当时的浏览器。所以这些新的函数附带了对可选参数定义的标签 <CFARGUMENT>, 它有两种不同的设定方式:
REQUIRED="yes" 如果指定参数不存在, 将提示错误。TYPE, 则会对传入参数的内容进行检查, 让传入的参数必须符合指定的格式。REQUIRED="no", 您可以对参数指定一个默认值。在四个函数中, <CFARGUMENT> 都定义了 browser 参数, 允许传递任何数据类型, 如果参数没有提供默认值, 则使用默认的 CGI 变量。
前三个函数基本上都跟前面看到的相同, 但第四个函数跟前面比起来就有较大的不同。第四个函数不像前三个函数, 各自验证一种特定的浏览器, 而是改成一次验证三种浏览器。它的做法是将浏览器字符串作为参数传入前三个函数, 并将浏览器缩写回传给调用这个函数的程序代码。这比复制前三个函数的程序代码到这个函数里面好多了, 这个函数直接使用前三个函数, 且不是用 <CFINVOKE>, 而是直接把它们当成函数调用就行了, 语法简单。
Listing 3 文件名为 test.cfm, 用来测试 browser.cfc 中所有的方法。
在 CFC 的定义里面, 使用了 HINT 和 RETURNTYPE 属性, 那么这个属性的内容会出现在哪呢?原来 CFC 可以自动产生自我描述文档, 这种自我描述文檔可以让我们清楚地了解每个方法的用途, 以便轻松的了解每个步骤。
有两种方法能呈现 CFC:
HINT 和 RETURNTYPE 等)<CFINVOKE> 标签格式。其实还有更多的信息需要介绍, 鉴于篇幅关系, 这里就不再继续往下写。
CFC 在简单的 CFML 中展现了强大对象应用能力, 您可以使用四个新标签来创建 CFC, 另存为 .cfc 文件, 并使用 <CFINVOKE> 标签调用它。但我们在此仅提到了表面的内容, 迄今我们学会的 CFC 的作用只比自定义标签的功能强一点点而已。下个月我将向大家介绍多种 CFC 的调用方式、如何使 CFC 持续、如何在 CFC 中使用结构和继承等等。