
Ben Forta
Senior Product
Evangelist de
ColdFusion
La reutilización del código es una práctica buena. De hecho, tanto es así que Macromedia ColdFusion permite reutilizar el código de varias maneras, desde inclusiones sencillas hasta etiquetas personalizadas y funciones definidas por el usuario. En los últimos años, los desarrolladores de ColdFusion han llegado a entender estos métodos, y los mejores de ellos han hecho un esfuerzo consciente por aprovechar la reutilización del código a fin de crear mejores aplicaciones.
Luego, justo cuando todo había quedado claro y se entendía bien, las cosas se complicaron.
Los componentes de ColdFusion (CFC) son los nuevos elementos fundamentales de las aplicaciones que se han incorporado en Macromedia ColdFusion MX. Logran lo que parecía imposible: unen la potencia de los objetos con la sencillez de CFML.
Los CFC permiten, y hasta promueven, la creación de aplicaciones estructuradas. De entre todas las opciones para la reutilización del código, los CFC son los que más se asemejan a las etiquetas personalizadas. No obstante, también existen diferencias muy importantes entre los dos:
En resumen, los CFC y las etiquetas personalizadas son bastante diferentes. A pesar de que su funcionalidad tiene algunas cosas en común, en realidad no resuelven los mismos problemas.
Veamos un ejemplo. El ejemplo de código a continuación, user.cfc, resume y encapsula el procesamiento del usuario. Contiene tres métodos:
Éste es el código de user.cfc:
<!--- User component ---> <CFCOMPONENT HINT="User processing"> <!--- List users method ---> <CFFUNCTION NAME="List" RETURNTYPE="query" HINT="Get complete user list"> <!--- Get users ---> <CFQUERY NAME="users" DATASOURCE="exampleapps"> SELECT EmployeeID AS UserID, FirstName, LastName FROM tblEmployees ORDER BY LastName, FirstName </CFQUERY> <CFRETURN users> </CFFUNCTION> <!--- Get user method ---> <CFFUNCTION NAME="Get" RETURNTYPE="query" HINT="Get a complete user record"> <CFARGUMENT NAME="UserID" TYPE="string" REQUIRED="true" HINT="Employee ID is required"> <!--- Get user email ---> <CFQUERY NAME="user" DATASOURCE="exampleapps"> SELECT EmployeeID AS UserID, FirstName, LastName, Title, Email, Phone, DepartmentName FROM tblEmployees, tblDepartments WHERE tblEmployees.DeptIDFK=tblDepartments.DepartmentID AND EmployeeID='#ARGUMENTS.UserID#' </CFQUERY> <CFRETURN user> </CFFUNCTION> <!--- Get user method ---> <CFFUNCTION NAME="GetEMail" RETURNTYPE="string"> <CFARGUMENT NAME="UserID" TYPE="string" REQUIRED="true" HINT="Employee ID is required"> <!--- Get user record ---> <CFQUERY NAME="user" DATASOURCE="exampleapps"> SELECT Email FROM tblEmployees WHERE EmployeeID='#ARGUMENTS.UserID#' </CFQUERY> <CFRETURN user.Email> </CFFUNCTION> </CFCOMPONENT>
La maravilla de user.cfc es que elimina de la aplicación toda interacción con la base de datos. En lugar de tener que usar <CFQUERY> para obtener una lista de usuarios, se podría hacer lo siguiente:
<!--- Get user list ---> <CFINVOKE COMPONENT="user" METHOD="List" RETURNVARIABLE="ListRet">
El valor que devuelve esta llamada <CFINVOKE> es una consulta y se puede usar como tal.
Aquí hay otro ejemplo, esta vez para mostrar la dirección de correo electrónico de un usuario:
<!--- Load user object ---> <CFOBJECT COMPONENT="user" NAME="usrObj"> <!-- Display email address ---> #usrObj.GetEMail(URL.userid)#
En este caso el componente de usuario se carga como un objeto (en el ámbito predeterminado VARIABLES, ya que no se especificó otro), el cual luego se utiliza para ejecutar un método determinado.
Ahora que se ha visto lo que se puede hacer con un componente de ColdFusion, veamos por qué se debe hacer. La mayoría de los desarrolladores de ColdFusion escriben código "spaghetti": un solo archivo de CFML que con frecuencia contiene consultas de bases de datos, salida HTML, formularios, JavaScript, lógica comercial (en forma de declaraciones CFML) y más. Este tipo de código no sólo no se puede volver a utilizar, sino también es difícil de mantener y no se ajusta a escala. Es por esto que los desarrolladores con más experiencia utilizan etiquetas personalizadas y otras formas de reutilización del código, como ya se mencionó.
Aun así, las etiquetas personalizadas no ofrecen la mejor opción. Éstas fueron diseñadas para crear una caja negra y encapsular la funcionalidad, lo cual esencialmente significa tomar bloques de código CFML y empaquetarlos para la reutilización. Las etiquetas personalizadas son ideales para resumir el código de menús, encapsular la integración de procesamientos de pago y aun para representar resultados. Las etiquetas personalizadas no fueron diseñadas para el desarrollo de aplicaciones que realmente tienen varios niveles. Es aquí donde los CFC salen a relucir.
Veamos el ejemplo anterior de user.cfc:
Como consecuencia de estas cualidades, los desarrolladores pueden utilizar los CFC de muchas maneras diferentes. Éste es el concepto básico de las aplicaciones con niveles —la separación de contenido y presentación— y los CFC son los elementos básicos con los cuales se crean los niveles de esas aplicaciones.
Los componentes de ColdFusion se utilizan para crear código reutilizable. Es por eso que deben escribirse con ese propósito. Esto significa que los CFC nunca deberían hacer suposiciones en cuanto al entorno de operación. Por ejemplo:
SESSION a menos que ellos mismos las definan (por ejemplo, si todo el procesamiento SESSION está encapsulado dentro de un CFC). Es peligroso suponer que uno conoce el entorno en el cual se usarán los CFC; después de todo, las variables SESSION podrían no existir. Si requiere una variable, ésta se le debería pasar a usted.En resumen, dentro de un CFC nunca se deberá suponer que uno sabe algo acerca de dónde proviene la solicitud, para qué sirve la solicitud, para qué se utilizarán los datos ni cualquier otra cosa. Los CFC deberían poder ser independientes. El escribir código con el propósito de reutilizarlo lo exige.
Si los componentes de ColdFusion no pueden hacer suposiciones acerca del entorno en el cual se usarán, entonces no se pueden utilizar para representar resultados. Ya que se trata de separar el contenido de la presentación, los CFC deberán devolver datos, no preocuparse de embellecerlos o de generar HTML del lado del servidor. Si se escribe un CFC correctamente, puede ser utilizado por muchos tipos de clientes, entre ellos:
Para poder brindar soporte a varias formas de presentación, solamente se debe cambiar la capa de presentación, no la capa de contenido. Los CFC solamente procesan contenido —lógica y procesamiento que es común independientemente de la presentación— de manera que los CFC no deberían generar páginas terminadas. Es perfectamente razonable (y aun recomendable) que un CFC devuelva datos seguidos de un grupo de páginas que presentan los datos de diferentes maneras. Y si es necesario reutilizar a nivel de la presentación, las etiquetas personalizadas son ideales para esa tarea. Su sintaxis, sobre todo el soporte para los pares de etiquetas y etiquetas hijo, hace que la tarea de aplicar presentación al contenido devuelto sea algo fácil y sin contratiempos.
Desde luego, toda regla tiene su excepción: los CFC sí pueden representar el contenido. Pero si se toma este camino, debe tenerse cuidado de no terminar donde se comenzó, es decir destruyendo la separación deseada entre la presentación y el contenido. Si desea usar los CFC para representar contenido, considere el uso de herencia en los CFC: cree un CFC básico que contiene todo el procesamiento de contenido y luego amplíelo utilizando una serie de CFC, uno para cada tipo de presentación y cada uno con su método de presentación propio. Esta opción es completamente factible, pero es posible que sintácticamente las etiquetas personalizadas sean más idóneas para esta tarea.
Acerca del autor
Ben Forta es "senior product evangelist" de Macromedia y autor de varios libros, entre ellos ColdFusion 5 Web Application Construction Kit y la continuación, Advanced ColdFusion 5 Development. Ben está actualmente escribiendo varios libros nuevos sobre ColdFusion MX. Para obtener mayor información visite el sitio web en inglés: www.forta.com*. Puede comunicarse con Ben en ben@forta.com (en inglés, por favor).