Disponible la primera versión de SURFORCE-CORE

La idea es tal cual se cuenta en el sitio oficial de Code Google, el proyecto SURFORCE-CORE busca compartir algo de experiencia con respecto a intentar trabajar en varios proyectos con Zend y busca, más que aumentar la productividad, no perderla... ¿pero cómo?


Con los proyectos conjuntos de SURFORCE-BASE, SURFORCE-LIBRARY y SURFORCE-MODULES se buscó tener de alguna forma una "arquitectura" común para aprovechar en cada nuevo proyecto. Evolucionando la idea original, SURFORCE-CORE sustituye a SURFORCE-BASE, este último funcionaba como un template que permitía usarlo como "base" pero luego lo modificábamos y tendríamos uno distinto para cada nuevo proyecto.

Ahora, con "CORE", la idea es usar siempre el mismo, como una aplicación que irá mejorando, y que tendrá todas las funcionalidades básicas para sistemas simples y repetitivos, como CMS o Admin's, y que posteriormente se diferenciarán no en el CORE (que es el mismo), sino, en su configuración y en sus módulos.

Esta primera versión resuelve varios problemas que surgieron durante el desarrollo de distintos proyectos:
  1. A diferencia de BASE, que todo partía de la raíz del proyecto, ahora el "document root" para el servidor Apache es solo el directorio "html" y el resto de la aplicación queda oculto en un nivel no accesible desde el exterior (seguridad, configuración sugerida por Zend).
  2. El CORE puede ser igual, pero los módulos deben poder ser dinámicos: generalmente todos los bootstrap (index.php) de sistemas ZF incluyen varias líneas "a fuego" donde se especifica la ruta donde encontrar los controllers para cada módulo. Esto fue sustituido por una carga dinámica donde obtiene la lista de módulos a partir del config.ini (archivo que será siempre distinto según el proyecto).
  3. Diferenciación de ambientes Desarrollo / Producción: como bien supo enseñarnos sistemas como Ruby On Rails, ahora se crean por lo menos dos ambientes, uno de desarrollo y otro de producción, con distintas configuraciones de bases de datos y distintos niveles de mensajes de error (por ejemplo, en producción no se envían a pantalla mensajes de error).
  4. Mayor configuración a partir del config.ini: definición de flags como debug (para habilitar rutinas de mayor detalle en los logs), ambiente de desarrollo (poder diferenciar distintas bases de datos), id de aplicación (poder contar con una única tabla de menú para posibilitar un menú dinámico a partir del id de aplicación), módulo de arranque por defecto, timezone, etc.
  5. El módulo "default" contendrá toda la información común para todos los proyectos: el layout por defecto, models genéricos (como el manejo de usuarios de la aplicación, etc), login a la aplicación, administración de los usuarios, etc.
  6. Carga dinámica de porciones de css y javascripts por controller: en la práctica me he dado cuenta que uno o más javascripts para todo el sitio era -en la mayoría de los casos- poco flexible (principalmente trabajando en un equipo de varios desarrolladores). Por consiguiente se agregó la posibilidad que por cada controller el layout busque un archivo con el mismo nombre del controller en ejecución pero con extensión .js y/o .css, permitiendo trabajar más libres de tener que mantener una nomenclatura común para absolutamente todo el sitio y estar cargando con funciones o estética que solo se aplican en controllers específicos (evitar que se repitan nombres de funciones, id's, etc).
  7. Se agregan cuadros de mensajes genéricos para el sistema: lo cual permiten enviar al usuario mensajes de información, alertas, etc, con un simple div, que a su vez se puede animar con jQuery para poder capturar la atención del usuario.
Hay que recordar que CORE nos permite tener un mismo sistema genérico para aprovechar entre varios sistemas similares que pueden a su vez estar en distintos servidores y que podrán ser adaptados con la simple configuración de su .ini y la carga de información en las tablas correspondientes. Posteriormente solo nos preocuparemos de crear módulos e instalarlos en el CORE correspondiente, con la ventaja de poder mover el módulo entre sistemas y continuar trabajando.

En resumen

Creo que se ha hecho un avance interesante que puede beneficiarnos a todos, tener una estructura genérica que resuelva los problemas comunes que encontramos a la hora de crear aplicaciones muy similares, y con simple configuración o creación de módulos poder cambiar su comportamiento y ser más productivos.

Destaco lo "simple", sin entrar en grandes extensiones complejas de código, con un poco de creatividad bien aplicada se pueden obtener beneficios sustanciales en la productividad de un equipo de trabajo.

En los próximos días iré agregando más información y tal vez hasta un screencasts contando un ejemplo completo de instalación y prueba.

PD: están todos invitados a participar en el foro de discusión y colaborar con su desarrollo.

Reglas básicas para trabajar con clases bajo PHP (actualizado)

Discutiendo sobre el tema en un foro hice el siguiente resumen básico de cómo deberíamos trabajar con clases bajo PHP:
  1. Una clase debe estar en un solo archivo/fichero, y el nombre del archivo/fichero debe ser el mismo que el nombre de la clase. Por ej, "Cliente.php" y la clase internamente debe llamarse "Cliente", en "ningún caso" [1] los nombres deben diferir (simil Java).
  2. Cada clase debe manejar su relación con otras clases de forma independiente de las clases con las cuales interactúa: para que una clase sea consistente esta debe saber a qué clases llamar para poder trabajar, sin importar que otra clase con la que debe relacionarse comparta una misma relación. A pesar que PHP permita colocar todos los include/require a las clases en un archivo centralizado (como muchas veces se hace en "index.php") , debemos evitarlo. Lo único que logramos es que la clase sea inconsistente en otro contexto al fallar porque ella no sabe resolver sus relaciones (imaginemos que una de esas clases no se usará en index.php, por lo tanto no estará la lista de include/require de clases que necesita para poder funcionar).
  3. En la relación entre las clases debes usar require_once, lo que resuelve si dos clases que se relacionan entre sí dependen a su vez de la misma clase, por consiguiente solo se invoca una vez, y seguimos manteniendo la independencia de la clase, ya que si nos llevamos una de esas clases a otro contexto, esta seguirá funcionando correctamente y permitirá el reuso normal de la misma sin dar ningún tipo de error de "clase ya requerida" (si usas solo include o require, no puedes llamar dos veces a la misma clase, por eso existen include_once y require_once).
  4. En un mismo contexto, nunca redefinir la misma clase, ya que pierde consistencia el diseño del sistema. Por ej, en un sistema contable tener una clase Cliente que según la clase que la llame puedan "reescribir" internamente la clase para que su diseño sea distinto a la clase original. Una clase debe ser única en un mismo sistema, no puede ser que existan dos versiones de la implementación de una misma clase.
  5. Anexo: debemos usar todos el mismo estándar de codificación (Zend)
Originado a partir de una consulta en un foro: "¿Redeclarar un clase?"

Notas complementarias

  • [1] - Estamos hablando de lo básico de POO para PHP, particularmente este punto puede variar como lo hace trabajar con una herramienta como Zend Framework, ya que PHP no encuentra por sí solo la ubicación física de una clase usan la "artimaña" de colocar en su nombre la ruta para llegar a ella. Esta práctica no es un "estándar" y debería en algún momento caer en desuso si se implementa correctamente el manejo de "namespace" en alguna versión futura de PHP. Pero volvemos al principio, con esta práctica el nombre de la clase queda distorsionado, ya que ahora, además del nombre está la ruta para llegar a la clase y esto es solo por un tema de la incapacidad de PHP y no tiene nada que ver con la POO (gracias GeL/T0 por tus valiosos comentarios ;-))

Entradas populares