Para el diseño de aplicaciones con sofisticados interfaces se utiliza el patrón de diseño Modelo-Vista-Controlador. La lógica de un interfaz de usuario cambia con más frecuencia que los almacenes de datos y la lógica de negocio. Si realizamos un diseño ofuscado, es decir, un pastiche que mezcle los componentes de interfaz y de negocio, entonces la consecuencia será que, cuando necesitemos cambiar el interfaz, tendremos que modificar trabajosamente los componentes de negocio. Mayor trabajo y más riesgo de error.
Se trata de realizar un diseño que desacople la vista del modelo, con la finalidad de mejorar la reusabilidad. De esta forma las modificaciones en las vistas impactan en menor medida en la lógica de negocio o de datos.
Elementos del patrón:
Un modelo puede tener diversas vistas, cada una con su correspondiente controlador. Un ejemplo clásico es el de la información de una base de datos, que se puede presentar de diversas formas: diagrama de tarta, de barras, tabular, etc. Veamos cada componente:
Un ejemplo de MVC con un modelo pasivo (aquel que no notifica cambios en los datos) es la navegación web, que responde a las entradas del usuario, pero no detecta los cambios en datos del servidor.
El diagrama de secuencia:
Pasos:
Bien, pero esto ¿cómo se implementa? Existe una pequeña dificultad: la mayor parte de las herramientas de desarrollo incorporan en las clases de la vista gran parte o todo el procesamiento de eventos. Con lo que el controlador queda semioculto dentro de la vista. A pesar de ello, podemos acercarnos bastante al patrón. En el siguiente ejemplo en Java, el objeto vista es un Applet AWT. El controlador (controlador.java) puede gestionar el clic en un botón, de tal forma que recoge datos por medio del Modelo (model.cargar_texto(..)) y los manda a la Vista (el applet) para su actualización (vista.mostrar_texto( )):
/****************************************************************
Responde al click en botón "abrir"
La respuesta al evento es hacer que se abra en la vista
el archivo correspondiente a la referencia seleccionada en el combo box
****************************************************************/
void b_abrir_actionPerformed(ActionEvent e) {
...
String texto_archivo = model.cargar_texto( indice_ref ); // Obtener texto de archivo
/*** Si la carga de archivo es ok, lo muestro. Si no, aviso de error ****/
if (texto_archivo != null) {
vista.mostrar_texto(texto_archivo); // Mostrar texto
vista.mostrar_aviso("Carga de " + path + " completada.");
}
else
vista.mostrar_aviso("Error en la carga de " + path);
}