Diciembre 10th, 2009 by John Carlos Arrieta Arrieta
Cordial saludo para todos..
Finalizando este año he decidido aclararles a los estudiantes algunas dudas que me han consultado sobre la implementación del patrón de arquitectura MVC en el desarrollo de aplicaciones Web escritas en PHP5 y el objetivo de este articulo es mostrarles mi propia implementación personal sobre este importante y antiguo Patrón Arquitectónico de Software, algo que he realizado hace unos tres o cuatro años cuando realice mi primera aplicación formal en en PHP, de paso aprovecho para desenmascarar a ciertos personajes por hay que están utilizando mi implementación y algunas de las clases de mi autoria en aludiendo que fueron hechas por ellos, como por ejemplo la clase ManejadorBasedatos y mi forma de hacer POJOS en PHP, con esta actitud en realidad siguen demostrando su falta de fundamentación teórico practica y su gran capacidad para montar un circo de falsedad, hipocresía y nociva envidian.
Para comprender mejor la intención de este articulo les recomiendo leer este otro articulo similar que he realizado para Java.
Como todos ya debe saber MVC o Model View Controller traducido al español como Modelo Vista controlador, es un antiguo patrón arquitectónico y no un patrón de diseño (esta es una de muchas fallas de fundamentación académica que tienen los sujetos descritos al inicio d este articulo) como algunos creen, los fundamentos de esto radica básicamente tener bien claro que los patrones de diseño de software fueron creado para solucionar de forma estándar problemas comunes en el diseño y desarrollo de software orientado a objetos, mientras que los patrones de arquitectura de software apuntan a la solución de otro tipo de problemas que se presentan en la organización estructural de los elementos que conforman el software.
El patrón MVC fue creado mucho antes de aparecer el análisis y diseño orientado a objetos, usado inicialmente para solucionar el problema de código espagueti, al que fácilmente llegaban los programadores que escribían programas basados en análisis y diseño estructurado (basado en funciones).
Básicamente este patron recomienda que la arquitectura estructural de todo software se piense, construya y mantenga utilizando las siguientes tres capas:
Una primera capa denominada View (Vista) para colocar todos los recurso que se utilizan para presentar datos e interactuar con el usuario (todos los controles de Interfaz de Usuario, ya sea basada en Texto, Táctil, de Voz, de señales Electrónicas o Gráfica, reportes, imagenes, sonido y video, etc),
Otra llamada Model (Modelo), donde se deben encontrar todos los recursos que se utilizan para realizar operaciones de propias del programa o sistema en desarrollo, estas operaciones conocidad como Negocio del sistema, pueden ser clasificadas en:
operaciones de persistencia, responsables de el almacenamiento, eliminación, actualización y recuperación de datos del programa, ya sea en memoria RAM o en un medio de almacenamiento de bytes,como lo puede ser un sistema de gestión de bases de datos.
Operaciones de lógica esenciales para dar sentido propio al sistema, tal es el caso de operaciones que realizan cálculos contables, matemáticos, estadísticos, operaciones para sistematizar alguna regla, norma o estándar o proceso especifico, se puede decir que esta capa da solución el problema que se quiere asistir mediante el desarrollo del software, son la esencia o el corazón del sistema, algo conocido comúnmente como núcleo o kernel
Y una ultima capa denominada Controller (Controlador), donde se colocan todo los recursos que tienen el código necesario para administrar el flujo de trabajo que proviene desde la capa de Vistas hacia la capa de Modelo, su función es tan importante como la función que cumplen los elementos de las otras dos capas, los elementos que contien al capa de contol permiten interpretar o traducir todas las peticiones que realizan los usuario desde la Vista, en peticion ejecutables por el sistema desde la capa de Modelo, para entenderlo mejor, pensemos en el Controlador como un director de orquesta (orquestador), el cual indica a todo los músicos de la orquesta que tan alto o bajo deben tocar un instrumento, cuando tocarlo, cuando sostener una nota, cuando soltarla, cuando parar y cuando seguir, es importante anotar que son los musicos los que en realidad realizan el trabajo final que desea escuchar el espectador, puesto cada uno de ellos mas que nadie sabe y conoce su respectivo instrumento musical, pero sin la organizacion de un director que CONTROLE de forma sincrizada todos los trabajo o toques, seguro que los musicos perderian el ritmo y todos querrían tocar a su manera una misma pieza musical, como resultado el usuario o espectador en este caso obtendia acambio una mala experiencia al escuchar el trabajo realizado por dicha orquezta.
Hagamos unas cuantas equivalencias entre este ejemplo que les acabo de dar y el patrón MVC para la construcción de software:
- Los músicos, los instrumentos y las letras de cada pieza musical o simplemente partituras son equivalentes a los elementos de se encuentran en la capa de Modelo, puesto que ellos son la maquinaria de la orquesta, son los que realizan el esencial o fundamental, generando información útil para el usuario.
- El repertorio de melodías o piezas que la orquesta tienen para ofrecer a los espectadores, es equivalente los elementos que se encuentran en la capa de Vistas, puesto que es con ellos los usuarios o espectadores se comunican con la orquesta para que esta les pueda satisfacer sus necesidades, si dentro del repertorio no se encuentra una determinada pieza musical (o función en el contexto de un software), quiere decir que esta orquesta (software en nuestro caso puntual) no esta preparada para realizar ese trabajo musical (servicio u operación en términos de software).
- El director de orquesta es equivalente a los elementos que se encuentran en la capa de Controlador, ya organiza, controla o dirige el flujo de trabajos realizados por los Músicos, con el fin de satisfacer una solicitud emitida por el usuario atravesé de mediante el uso del repertorio de la orquesta, el director traduce esta solicitud terminotes de operaciones que deben ser ejecutadas o realizadas por los músicos, sabiendo perfectamente quien debe y no debe realizar cada tareas especifica, asi mismo trabajan los controladores de un software, los cuales normalmente son clases que suministran ordenes a otras clases del sistema para que esta deban realizar o parar ciertas operaciones y entregar un resultado al final de dicha operación, que en la mayoría de las veces este resultado es entregado a las clases de la Vista para que estas deban mostrarlo al usuario en forma legible.
Esta manera de organizar la estructura de elementos que conforman a un software trae muchas ventajas a cambio, entre las cuales se encuentan:
Separación clara de las instrucciones de código que ejecutan tareas de presentación, de las instrucciones de código que ejecutan tareas del negocio, evitando el caótico y desagradable código espagueti.
Identificación rápida y presisa de la ubicación los elementos del software segun la funcionalidad que ofrece cada uno de ellos, en caso de realizar un mantenimiento al sistema.
Asignar responsabilidades y cargas de programación a los desarrolladores del software según la experiencia y el nivel de especializacion que poseen con respecto cada capa del sistema.
Trabajar en orden a las siglas MVC de este patrón, las cuales no están colocadas de esta manera por puro capricho, sino que obedecen a un principio basico del analisis y diseño de software, el cual indica que primero se debe hacer mucho análisis y diseño para comprender las reglas que dominan el problema o negocio, una vez comprendido debe ser materializado en términos de instrucciones ejecutables por el PC, iniciando con la primera capa del software es decir con la M de Modelo, ya que esta capa contiene gran parte de la solucion informática necesaria, luego se continua con la V de Vistas, es decir, se construyen todos los elementos de interfaz de usuario que permiten solicitar la ejecución de operaciones ubicadas en el modelo ya construido, por ultimo se termina con la C de Controlador, escribiendo y construyendo todos los elementos que permiten conectar, traducir y redireccionar las solicitudes que vienen de la Vista hacia el modelo y de forma contraria, la información generada por el Modelo y la entrega o notifica a la Vista correspondiente, tal y como lo indica la siguiente gráfica que he preparado en el otro articulo sobre MVC y Java.

Patron MVC
Bueno una cosa es la teoría otra muy distinta es llevarlo a la practica, sobre todo en aplicaciones distribuidas como las aplicaciones Web basadas en HTTP, aunque actualmente con las tecnologías que fundamenta a la Web2.0 es mucho mas fácil, lo digo por que para que nuestra implementación sea 100% compatible a la teoría del patrona MVC se necesita de mecanismos que permitan actualizar a la vista sobre cambios realizados en el modelo y viceversa, función propia del Controlador, en aplicaciones de escritorio esto es una tarea muy simple, porque no esta de por medio el protocolo HTTP y toda la vista se encuentran en un solo lado, en cambio en las aplicaciones Web no como sucede igual, ya que las vistas tanto en el servidor como en el cliente (normalmente un navegador) , sumándole la característica de desconexion que tiene con la que funciona protocolo HTTP, hacen lago complicado implementar un excelente patron MVC.
Bueno a qui les coloco una simple implementación del patrón MVC para aplicaciones Web con PHP5 que realice hace algunos años, tiene todos sis elementos a excepción del del mecanismo que notifica de forma automática a al Vista sobre cambios en el Modelo y viceversa, algo que explicare en otro próximo articulo, me refiero a dos patrones de diseño de comportamiento, uno llamado ActiveRecord y ObserverOservable, los cuales son explotados de forma intensiva por los hoy ya comunes Marcos de Trabajo o Framwork para desarrollo de aplicaciones Web.
Iniciamos con la creando una estructura de archivos como la que muestro a continuación

HTDOCS: Esta carpeta es el directorio de hosting u hospedaje de aplicaciones Web del afamado Servidor Web Apache, aquí se colocan los sitios que se desean poner al servicio de los usuario de la red (internet, MAN o LAN), es conocida como carpeta de servicios, es equivalente a la carpeta WWWROOT de otro igualmente famoso Servidor Web llamado IIS o Internet Information Server, de propiedad de Microsoft
AGENDA: Esta carpeta es la carpeta donde se encuentran alojados los ficheros (paginas_web.htm, ficheros_script.php, ficheros_images, ficheros_sonidos, ficheros_javaScript.js, ficheros_applet_java.class, ficheros_flash.swf, ficheros_xml, etc) que hacen parte de la aflicción de ejemplo que les he hecho.

Las carpetas WEB, CONTROL y MODELO representan a las respectivas capas del patrón MVC, y estas contienen los ficheros o recursos según si función en el sistema, tal y como lo explique anteriormente.
Carpeta Modelo

En este simple ejemplo solo contiene un solo archivo, el cual contiene el código de la clase Persona, la cual contiene la lógica necesaria para realizar operaciones de persistencia sobre la base de datos de de las personas que están hacen parte de la agenda.
Dentro del archivo modelo/Persona.php se encuentra escrita y bien definida una clase llamada Persona, la cual tiene toda la funcionalidad (lógica – negocio) necesaria para poder modelar un Persona del mundo real, por esta razón posee métodos que permiten setear (establecer valores) los posibles datos que pueden almacenarse en los atributos de una Persona.
Otras particularidades de un Persona guardada en una agenda del mundo real es que se pueda almacenar, actualizar, eliminar, consultar, enviar mensaje, listar, etc Estas operaciones realizadas sobre un Persona también son materializadas por la clase nuestra clase Persona.
La operación de registrar(), consultar(), modificar(), eliminar() y los listar()de la clase Persona pueden lanzar un excepción (error) durante su ejecución, lo que exige la notificación inmediata al usuario (actor) que utiliza el sistema durante la ocurrencia del error, para este que realice las correcciones necesarias, lo ideal es que el tratamiento y respuesta de notificación visual a estos errores o excepciones se realicen en una capa más arriba de la capa de Modelo MVC, es decir en la capa de Vistas, pero como el error ocurrió en la capa de modelo, entonces el patrón de diseño MVC sugiere que sea la capa de Control la encargada de notificar a la capa de Vista sobre dicho error, es por esto que los posibles errores se capturan y se tratan en la clase control/ManejadorPersona.php, redireccionando las notificación al fichero web/error.php que hace parte de las Vistas (GUI o interfaces graficas de usuario) con las que interactúan directamente con el usuario.
La carpeta Web

Contiene todos los archivos que representan Interfaces de usuario Web, como es el caso de las paginas HTML estáticas o generadas dinámicamente con código PHP, los archivos de multimedia como videos, Audio, etc, las imágenes como logos, iconos, eslogan, etc, los archivos que contienen código CSS para darle estilo a las páginas Web, archivos JS que contienen código JavaScript, que coloca controles GUI y realiza validaciones en las paganías Web, reportes y documentos ofimáticos en formato pdf. Word, xls, etc, en este caso se puede apreciar dos archivos cuyo nombre sugiere acciones del usuario, estos son mostrar_persona.php y registra_persona.php, los cuales son páginas Web que generan formularios dinámicos, permitiendo al usuario enviar datos a al controlador ManejadorPersonas de la capa de control, el cual le indica a la clase personas de la capa de modelo que ejecute las operaciones respectivas.
El archivo registrar_persona.php de la carpeta Web, básicamente es una pagina Web que envía datos de un formulario hacia el servidor apache, utilizando el método http/post, entre los datos que envía se encuentra un archivo que el usuario selecciona desde su cliente Web (navegador Web IE, FireFox, Opera, Safari, etc) mediante un control grafico de entrada HTTP del tipo fichero o file, que permite al usuario seleccionar el fichero y pueda ser enviado, el envió del archivo no funcionaria de forma correcta si se omitiera método post y el método de particionamiento múltiple de datos enctype=”multipart/form-data” del protocolo HTTP.
La pagina php registrar_persona envía sus datos hacia el controlador manager_Persona.php, adicionalmente se envía un parámetro de entrada HTTP del tipo oculto o hidden cuyo nombre es accion y cuyo valor es resgistrar <input type=“hidden” name=“accion” value=“resgistrar ” />.
Controladores (carpeta COTROL)

Contiene archivos con el código que ejecutable para realizar el trabajo de los controladores, como lo explique anteriormente tiene la principal responsabilidad de recibir los servicios o peticiones hechas desde las UI (interfaces de usuarios) que se encuentran en la carpeta y traducirlos a ejecuciones realizadas por la capa de la clase Persona que se encuentra en la carpeta Modelo, en este ejemplo he escrito dos controladores, uno para manejar las operaciones correspondientes a las personas y otro para manejar las operaciones correspondientes a las operaciones de conexión con el SMBD, que en este caso es el servidor MySQL, la verdad esta clase tiene más funciones de modelo por lo que se ocupa de la gestión de la persistencia, pero lo he colocado acá porque en realidad el SMBD es otro actor del sistema, es un ente externo que solicita información del sistema y envía información al mismo, así que es mi motivo, pero ustedes pueden colocarlo en la capa de modelo y hay estará muy bien.
Dentro de ManejadorPersona.php se encuentra escrita y bien definida una clase llamada ManejadorPersona ¸ la cual tiene la funciones para recoger los parámetros HTTP enviados por las vistas con sus respectivos valores.
Luego dependiendo del valor que traiga el parámetro acción, la clase control/ManejadorPersona ejecuta uno de varios servicios (acciones) implementadas en la clase Persona (capa modelo) que se encuentra escrita y bien definida en el archivo modelos/Persona.php.
Estas operaciones se realizan en el función ejecutarAccion(), de la clase ManejadorPersona, el cual a su vez llama a la función accionGuardarPersona () de esta misma clase, accionGuardarPersona () recupera crea un objeto de tipo Persona seteandole (uso de los métodos set) valores a los diferentes atributos (variables) del objeto Persona $this->persona, estos valores corresponden a los datos recuperados por el controlador al ser enviados por la pagina registrar_persona.php, luego de hacer esto el controlador llama al método (función) registrar() del objeto tipo persona, $this->persona->registrar().
La ejecución de la función registrar(), pueden ocasionar el lanzamiento de un error (Excepcion), que puede ocurrir por varios motivos, por ejemplo que la cedula de la nueva Persona ya este registrada en la base de datos o simplemente porque no existe conexión a la base de datos de Personas, esta posible eventualidad obliga a tener que vigilar vigila la ejecución de estas operaciones mediante un bloque
try{
Instrucciones (seteo y registro de Persona )
}
catch(Exception $er) {
Acciones a ejecutar en caso de error (terminar y enviar mensaje de error)
}
Si el seteo de valores y registro del objeto de tipo Persona se realiza sin errores, entonces el método accionGuardarPersona() de la clase ManejadorPersonas redirecciona (envía el control a otro lugar) al código php escrito en el archivo web/error.php, mediante el comando Location: URL del protocolo HTTP, el cual le dice al cliente Web (navegador Web) que localice otro recurso (fichero) ubicado en la URL indicada, esta URL puede llevar de forma adicional algunos parámetros, que para nuestro caso corresponden al mensaje de satisfacción y la ruta del enlace al cual se debe dirigir el usuario cuando vea dicho mensaje.
header(“Location: ../web/error.php?mensaje=$mensaje&enlace=index.htm”);
exit();
Si por el contrario durante el seteo o registro en la BD del objeto de tipo Persona ocurre un error (Excepción), entonces dicho error (el primero que ocurra) se captura mediante la instrucción catch( Exception $er ), de la clase ManejadorPersonas, esta instrucción redirección el control al fichero web/error.php pasándole el mensaje de error y la ruta del enlace al cual se debe dirigir cuando el usuario lea el mensaje.
catch(Exception $er){
$mensaje = $er->getMessage();
header(“Location: ../web/error.php?mensaje=$mensaje&enlace=vista_registro_Persona.html”);
exit();
}
Aquí les coloco un poco de codigo de la clase ManejadorPersona responsable de dirigir u organizar el flujo del trabajo del programa, indicando al modelo que función debe realizar almacenado los objetos de dicho modelo en la sesión.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| // Ejemplo de una función del controlador
public function accionEliminarPersona(){
// recuperar los datos del formulario y
// colocarlos en un objeto de la clase Persona
$this->accionRecuperaPersonaFormulario();
try{
// Ejecutar las funciones del modelo
$this->persona->eliminar();
// Guardar el objeto del modelo en la Sesion
$_SESSION['persona'] = serialize($this->persona);
// redireccionar a la Vista notificándole que hay
//datos en la sesión que pueden ser consultados
$msg ="Persona ".$this->persona->getCodigo()."fue modificada con exito";
header("Location: ../web/mostrar_persona.php?msg=$msg");
}catch(Exception $error){
// redireccionar a la Vista notificándole que hay
//que ocurrió un error en la capa de Modelo
$mensaje = $error->getMessage();
header("Location: ../web/mostrar_persona.php?msg=$mensaje");
exit();
}
} |
La Vista o interfaces de usuario (generalmente paginas generadas dinámicamente con código PHP), pueden recuperan los objetos del modelo almacenados en la sesión, consultan sus datos y los presentan al usuario en varios formatos.
1 2 3 4 5 6 7 8 9 10
| // Ejemplo de la recuperación de objetos en la sesión por parte de la capa de Vistas
// verificar si hay algo en la sesion
if( isset( $_SESSION['persona'] )){
// recuperas y reconstruir los objetos de la sesión
$persona = @unserialize($_SESSION['persona']);
// Recuperado el objeto de la sesión,
// este se pede borrar de la misma,
unset( $_SESSION['persona'] );
} |
Los objetos de la capa del modelo realizan las operaciones de persistencia y lógica según se la lógica del sistema, también conocida en Ingeniería del software como Negocio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| // Ejemplo de una función de la capa de negocio de
public function eliminar(){
// genrero el sql
$sql = "DELETE FROM Personas
WHERE ID = $this->codigo";
$basedatos = new ManejadorBasedatos();
try{
$basedatos->conectar();
$basedatos->modificar( $sql);
$basedatos->cerrar();
}
catch(Exception $error){
throw new Exception("Error al Eliminar la persona $this->codigo<br>". $error->getMessage());
}
} |
En la carpeta LIB encuentran algunos proyectos de software libre que he escogido para generar los reportes en PDF, aquí en esta carpeta se deben colocar todas las librerías (Componentes) adicionales que se integren con nuestra aplicación.
En la carpeta CONFIG podríamos colocar archivos XML o PHP para realizar configuraciones de pre y post instalación de nuestra aplicaciones, y justamente después de finalizar la el proceso de instalación, los borraríamos de forma automática.
Por último en la carpeta UTILIDAD se pudrían colocar todas, los cuales son necesarios para realizar tareas útiles, en este caso pueden escribir por ejemplo una clase llamada Utilidad, la cual se encuentre en el archivo utilidad.php de la carpeta útil, tendría métodos de utilería que permiten realizar acciones como:
Validar que un dato del tipo numérico (Entero o Real).
Validar que un dato no posea números
Validar que un email este bien formado (usuario@dominio)
Validar que una fecha tenga el formato AAAA-MM-DD o AAAA.MM.DD o AAAA/MM/DD y sea valida para el calendario gregoriano.
Validar si un fichero enviado tiene formato de imagen valida (para lo de la foto del Persona).
Validar que un dato no este vació.
Algunas de estas funciones podrían ser utilizadas para validar el correcto formato de los datos seteados en las propiedades de los objetos de tipo Persona, mediante los métodos setXXX de la clase Persona, que donde XXX corresponde al nombre de cada una de las propiedades de la clase Persona.
Descargar el código fuente del proyecto Ejemplo
Feliz navidad para todos y prospero año nuevo.
Que el nuevo año los inunde de ganas por estudiar, por trabajar, de salir adelante y sobre todos de hacer el bien siempre, pase lo que pase.
Mil bendiciones para todos.
375 Visitas hoy