Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
ITI-1005
El patrn MVC
El modelo representa la informacin con la que trabaja la aplicacin, es decir, su lgica de negocio. La vista transforma el modelo en una pgina web que permite al usuario interactuar con ella. El controlador se encarga de procesar las interacciones del usuario y realiza los cambios apropiados en el modelo o en la vista. La Figura 2-1 ilustra el funcionamiento del patrn MVC. La arquitectura MVC separa la lgica de negocio (el modelo) y la presentacin (la vista) por lo que se consigue un mantenimiento ms sencillo de las aplicaciones. Si por ejemplo una misma aplicacin debe ejecutarse tanto en un navegador estndar como un un navegador de un dispositivo mvil, solamente es necesario crear una vista nueva para cada dispositivo; manteniendo el controlador y el modelo original. El controlador se encarga de aislar al modelo y a la vista de los detalles del protocolo utilizado para las peticiones (HTTP, consola de comandos, email, etc.). El modelo se encarga de la abstraccin de la lgica relacionada con los datos, haciendo que la vista y las acciones sean independientes de, por ejemplo, el tipo de gestor de bases de datos utilizado por la aplicacin.
Ejemplo MVC
ITI-1005
Programacin simple
Utilizando solamente PHP normal y corriente, el script necesario para mostrar los artculos almacenados en una base de datos se muestra en el siguiente listado: Listado 2-1 - Un script simple
<?php // Conectar con la base de datos y seleccionarla $conexion = mysql_connect('localhost', 'miusuario', 'micontrasena'); mysql_select_db('blog_db', $conexion); // Ejecutar la consulta SQL $resultado = mysql_query('SELECT fecha, titulo FROM articulo', $conexion); ?> <html> <head> <title>Listado de Artculos</title> </head> <body> <h1>Listado de Artculos</h1> <table> <tr><th>Fecha</th><th>Titulo</th></tr> <?php // Mostrar los resultados con HTML while ($fila = mysql_fetch_array($resultado, MYSQL_ASSOC)) { echo "\t<tr>\n"; printf("\t\t<td> %s </td>\n", $fila['fecha']); printf("\t\t<td> %s </td>\n", $fila['titulo']); echo "\t</tr>\n"; } ?> </table> </body> </html> <?php // Cerrar la conexion mysql_close($conexion); ?>
El script anterior es fcil de escribir y rpido de ejecutar, pero muy difcil de mantener y actualizar. Los principales problemas del cdigo anterior son:
No existe proteccin frente a errores (qu ocurre si falla la conexin con la base de datos?). El cdigo HTML y el cdigo PHP estn mezclados en el mismo archivo e incluso en algunas partes estn entrelazados. El cdigo solo funciona si la base de datos es MySQL.
Ejemplo MVC
ITI-1005
Separando la presentacin
Las llamadas a echo y printf del listado 2-1 dificultan la lectura del cdigo. De hecho, modificar el cdigo HTML del script anterior para mejorar la presentacin es un folln debido a cmo est programado. As que el cdigo va a ser dividido en dos partes. En primer lugar, el cdigo PHP puro con toda la lgica de negocio se incluye en el script del controlador, como se muestra en La parte del controlador. La parte del controlador, en index.php
<?php // Conectar con la base de datos y seleccionarla $conexion = mysql_connect('localhost', 'miusuario', 'micontrasena'); mysql_select_db('blog_db', $conexion); // Ejecutar la consulta SQL $resultado = mysql_query('SELECT fecha, titulo FROM articulo', $conexion); // Crear el array de elementos para la capa de la vista $articulos = array(); while ($fila = mysql_fetch_array($resultado, MYSQL_ASSOC)) { $articulos[] = $fila; } // Cerrar la conexin mysql_close($conexion); // Incluir la lgica de la vista require('vista.php'); ?>
El cdigo HTML, que contiene cierto cdigo PHP a modo de plantilla, se almacena en el script de la vista, como se muestra en La parte de la vista La parte de la vista, en vista.php
<html> <head> <title>Listado de Artculos</title> </head> <body> <h1>Listado de Artculos</h1> <table> <tr><th>Fecha</th><th>Ttulo</th></tr> <?php foreach ($articulos as $articulo): ?> <tr> <td><?php echo $articulo['fecha'] ?></td> <td><?php echo $articulo['titulo'] ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
Ejemplo MVC
ITI-1005
Una buena regla general para determinar si la parte de la vista est suficientemente limpia de cdigo es que debera contener una cantidad mnima de cdigo PHP, la suficiente como para que un diseador HTML sin conocimientos de PHP pueda entenderla. Las instrucciones ms comunes en la parte de la vista suelen ser echo, if/endif, foreach/endforeach y poco ms. Adems, no se deben incluir instrucciones PHP que generen etiquetas HTML. Toda la lgica se ha centralizado en el script del controlador, que solamente contiene cdigo PHP y ningn tipo de HTML. De hecho, y como puedes imaginar, el mismo controlador se puede reutilizar para otros tipos de presentaciones completamente diferentes, como por ejemplo un archivo PDF o una estructura de tipo XML.
Ejemplo MVC
ITI-1005
El controlador modificado se puede ver en La parte del controlador, modificada. La parte del controlador, modificada, en index.php
<?php // Incluir la lgica del modelo require_once('modelo.php'); // Obtener la lista de artculos $articulos = getTodosLosArticulos(); // Incluir la lgica de la vista require('vista.php'); ?>
Ahora el controlador es mucho ms fcil de leer. Su nica tarea es la de obtener los datos del modelo y pasrselos a la vista. En las aplicaciones ms complejas, el controlador se encarga adems de procesar las peticiones, las sesiones de los usuarios, la autenticacin, etc. El uso de nombres apropiados para las funciones del modelo hacen que sea innecesario aadir comentarios al cdigo del controlador. El script del modelo solamente se encarga del acceso a los datos y puede ser reorganizado a tal efecto. Todos los parmetros que no dependen de la capa de datos (como por ejemplo los parmetros de la peticin del usuario) se deben obtener a travs del controlador y por tanto, no se puede acceder a ellos directamente desde el modelo. Las funciones del modelo se pueden reutilizar fcilmente en otros controladores.
Ejemplo MVC
ITI-1005
Como se puede comprobar, la capa de acceso a datos no contiene funciones dependientes de ningn sistema gestor de bases de datos, por lo que es independiente de la base de datos utilizada. Adems, las funciones creadas en la capa de abstraccin de la base de datos se pueden reutilizar en otras funciones del modelo que necesiten acceder a la base de datos.
Ejemplo MVC
Nota
ITI-1005
Los ejemplos de los listados 2-6 y 2-7 no son completos, y todava hace falta aadir algo de cdigo para tener una completa abstraccin de la base de datos (abstraer el cdigo SQL mediante un constructor de consultas independiente de la base de datos, aadir todas las funciones a una clase, etc.)