Más Modelo y menos Controlador en el patrón MVC

He tenido ocasión de acceder al código de algunas aplicaciones para su desarrollo y veo un patrón que se repite con frecuencia y que demuestra que el desarrollador no está entendiendo el patrón de diseño de software Modelo Vista Controlador (MVC). Veo modelos pequeños que, a parte de la validación de los datos, poca más lógica contienen. Por otro lado y como no podía ser de otro modo, unos controladores gigantes para compensar los raquíticos modelos.

En el fondo una página web es tan solo un interfaz a la base de datos. Siendo aun más generalista: es tan solo un interfaz a un origen de datos (datasource). Ese origen de datos podría un servicio web SOAP, la API Rest de Twitter o cualquier otro, póngale imaginación. Si creamos ese interfaz, esa web, es por razones como que el usuario medio no tiene porque saber SQL ni mucho menos conocer la estructura de la base de datos, porque un XML de medio megabyte no nos resulta muy agradable a los humanos, etc. Siendo aun más generalistas podríamos decir que la inmensa mayoría de las aplicaciones, web o no, son “tan solo” eso. Por lo tanto, es la base de datos lo más importante y siendo los modelos los encargados de interactuar con ella, tienen un peso fundamental en una aplicación que pretende seguir el patrón MVC. Tema para otro artículo es como frecuentemente las bases de datos están mal diseñadas, saltándose a la torera las Formas Normales y no por optimizaciones en sitios con mucho tránsito. Esta alegría para diseñar el modelo de la base de datos la he llegado a ver incluso en personas que han recibido formación en la ingeniería de software.

Para poder dar un ejemplo de infrautilización de los modelos imaginemos una aplicación donde los usuarios, al crear o actualizar su perfil, opcionalmente pueden incluir una imagen a modo de avatar. Es obvio que es en el modelo donde deberemos validar si el fichero no excede un tamaño máximo y si es del tipo esperado: una imagen. Lo que no es tan obvio es que en el modelo también debe ir toda la lógica para tratar posibles errores manejando el fichero en el servidor. Tendremos que mover el fichero desde su ubicación temporal a la definitiva y talvez tengamos que realizar operaciones como cambiarle el nombre o crear un directorio donde alojarlo y lo que no es tan obvio es que esas operaciones también deben hacerse en el modelo evitando la tentación de sobrecargar el controlador. Si el campo “avatar”, donde guardamos el nombre del fichero, no es obligatorio en la tabla, posiblemente primero guardaremos el nuevo usuario, luego realizaremos las operaciones con el fichero y si es felizmente renombrado y está en su ubicación actualizaremos la tabla con el nuevo nombre del avatar, de lo contrario informaremos al usuario de que si bien se pudo guardar su registro se produjo un error interno y no se pudo guardar la imagen que envió (por ejemplo haciendo saltar una regla de validación que no impida la inserción o actualización del usuario) En el controlador sólo haría esto o poco más:

if ($this->request->is('post')) {
    $this->User->create();
    if ($this->User->save($this->request->data)) {
        $this->Session->setFlash(__('The user has been saved'));
        $this->redirect(array('action' => 'index'));
    } else {
        $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
    }
}

Este ejemplo se puede generalizar a cualquier acceso a la base de datos para crear o actualizar un registro que dependa de otro factor ajeno a la operación. Otro caso típico es al realizar complejas búsquedas en la base de datos, toda la lógica debe estar en el modelo y desde el controlador llamar a la función del modelo, si por complejidad es necesario dicha función puede estar apoyada por otras funciones “protected” o “privated” del modelo.

Toda acción CRUD (Create, Read, Update and Delete) así como otras operaciones dependientes deben estar en el modelo. Si es nuev@ en el patrón MVC, antes de poner algo en el controlador piense bien si es el lugar más adecuado. Seguir la normal general de mantener los controladores pequeños y los modelos preponderantes le ayudará a desarrollar unas aplicaciones más fáciles de mantener y modificar.

– Editado el 10/03/2012 –

Lo que aquí he expuesto no sólo aplica al MVC, no sólo al desarrollo web sino a todo el desarrollo de software, es uno de los principios básicos de la ingeniería de software. Los datos y su estructura dominan, si no están bien toda lógica que opere sobre esos datos va a ser innecesariamente más compleja. Incluso aparece listado en las reglas de la “filosofía Unix“, según Eric S. Raymond. Aunque estas normas van más allá de Unix y aplican para el desarrollo en cualquier plataforma.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.