[ TEMIGA ]
¿Que es un Modelo? – MVC
Una de las cosas que se aprecia constantemente entre las comunidades de desarrolladores, es la vaga idea que suele existir sobre el manejo del MVC donde solo se tiene en mente el concepto de wikipedia y demas sitios donde se conceptualiza sobre el tema.
Resulta bastante difícil, de acuerdo a mi experiencia y el roce que he tenido con personas del área, ir de la teoría a la implementacion del concepto de lo que es MVC parece ser una camino ofuscado en el que muchos se pierden. La gran mayoría suele decir “estoy claro en lo es MVC…”, pero cuando se ve la aplicabilidad se termina dando cuenta que lo que dijó “estoy claro…” es inversamente proporcional.
Filosofía de un Modelo
Estos son “Lógica de Negocio” y son parte fundamental para el momento que se desarrolla una aplicación, un buen uso de estos nos permiten un gran poder al momento que se necesita escalar, mantener y rehusar código en una aplicación.; es un concepto muy simple, pero la complicacion esta en comprender lo que significa “Logica de Negocio” ya que muchos piensan que la única forma de tener “Lógica de Negocio” va estrecha y únicamente relacionada con una conexión de Base de Datos y esto no es asi!
La práctica mas común (en todos los niveles, no solo me refiero a usuarios novatos) es que dejan la lógica en los controladores, a medida que se deja código de la lógica de negocio en un controlador trae consecuencias garrafales a largo plazo siendo imposible su reutilizacion, traduciendoce en una mala implementacion (código espaguetti). Lo antes expuesto no es precisamente lo que fomenta MVC y POO donde la idea fundamental es el orden y reutilización del código.
Veamos un par de ejemplos para contextualizar.
El primero es un Modelo donde su lógica de negocio esta en una Base de Datos y por ende necesitamos una conexion a motor para trabajar con esa fuente de datos.
class Articulos extends ActiveRecord { public function ver($page=1,$ppage=10){ return $this->paginate('order: creat_at desc', "page: $page", "per_page: $ppage"); } public function ultimos($limit=10) { $today = date('now'); return $this->find('order: creat_at desc', "conditions: data >= $today", "limit: $limit"); } }
Lo que mencionamos arriba sobre la re-utilización de código y característica fundamental de la POO, si vemos el método ultimos() del modelo Articulos nos sirve para crear un RSS, widget (Partial en KumbiaPHP) con los artículos recientes, etc. es decir donde se necesite los últimos artículos.
El segundo es un Modelo para el manejo de fotos y su la lógica de negocio no esta ligada a una BD.
<?php /** * Carga la libreria upload **/ Load::lib('upload'); /** * Carga la libreria wideimage **/ //Load::lib('wideimage'); /** * Modelo para manipular las fotos de las personas * **/ class Foto { /** * Guarda la foto de una persona * * @param string $id id de la foto al guardar * @param string $file nombre de la foto * @return boolean **/ public function save ($id, $file) { if ($_FILES[$file]['error'] > 0) { Flash::error('Error: No se ha logrado subir el archivo'); return false; } if (! in_array($_FILES[$file]['type'], array('image/jpeg' , 'image/pjpeg' , 'image/gif' , 'image/png'))) { Flash::error('Error: Solo se admiten imagenes JPEG, PNG y GIF'); return false; } if ($_FILES[$file]['size'] > 600 * 1024) { Flash::error('Error: No se admiten imagenes superiores a 600KB'); return false; } if (Upload::image($file, "$id.jpg")) { $file_path = APP_PATH . "public/img/upload/$id.jpg"; // con marca de agua // $watermark = wiImage::load(APP_PATH . "public/img/logo.png"); // wiImage::load($file_path)->resize(160, 213, 'fill')->merge($watermark, 40, 175)->saveToFile($file_path); wiImage::load($file_path)->resize(160, 213, 'fill')->saveToFile($file_path); chmod($file_path, 0777); return true; } return false; } /** * Busca la foto y en caso de que exista retorna la ruta relativa respecto al directorio de imagenes * * @return string $id * @return string **/ public function get ($id) { if (is_file(APP_PATH . "public/img/upload/$id.jpg")) { return "upload/$id.jpg"; } return null; } /** * ELimina la foto del usuario * * @return string $id * @return string **/ public function delete ($id) { $filepath = APP_PATH . "public/img/upload/$id.jpg"; if (is_file($filepath)) { return unlink($filepath); } return false; } }
Como se aprecia en este segundo modelo no existe ninguna conexión a una BD y sigue teniendo lógica de negocio para la aplicación, esta historia también se puede repetir para un modelo de sessión, o como me comento el amigo Jesus Lara (Phenobarbital) tiene modelos que gestionan todas las operaciones de un servidor SAMBA.
| Imprimir artículo | Este artículo fue publicado por CaChi el Diciembre 29, 2009 a las 7:11 pm, y está archivado en Programación. Sigue las respuestas a esta entrada a través de RSS 2.0. Puedes dejar un comentario o enviar un trackback desde tu propio sitio. |







hace 6 meses
Excelente post cachi, muchos creemos (incluyendome) entender el patron de modelo MVC, pero no lo sabemos aplicar…..
hace 6 meses
yo tb creia que le entendia…pero te la pasas retandome asi que parece que no le entiendo muy bien :P
igual ya aprendere :)
hace 6 meses
@Perro sabe que lo hacemos por tu bien :-)… en KumbiaPHP nos esforzamos mas por tener Buenos desarrolladores, que buenos programadores son cosas totalmente distintas…
hace 6 meses
cachi sos un groso…recien al leer esto me doy cuenta como por ejemplo yo hacia todo el trabajo de subir una imagen en un controlador :(
Ha por cierto…deberias colocar un plugin para suscribirse a los comentarios…porque sino la gente no se entera cuando respondes :P
hace 4 meses
en breve como entiendo MVC
Modelo => Clases Operativas (Nuca ve a la Vista)
Controlador => Clases que llaman e interactúan con los Modelos y envía a la vista la información que resultante de la interación de los Modelos
Vista => solo Muestra la información que le proveyó el Controlador (Nunca ve al Modelo)
No se si tengo mal entendiendo algún concepto, creo que como tu he ido tratando de acoplarme a lo que dice el modelo si bien tener alguien que guié mas que el juicio propio y la poca documentación que existe en la red.
bueno y viendo el código me sale una consulta, que recuerdo algún día tuve y consulte con migo mismo xP
al manejar validaciones en los modelos por ejemplo:
if ($_FILES[$file]['error'] > 0) {
Flash::error(‘Error: No se ha logrado subir el archivo’);
return false;
}
desconozco que haga Flash::error, me imagino que en automático llamaría alguna pantalla y esta mostraría el error, pero puede que no..
bueno estuve manejado los try/catch entonces llegue a la conclusión que la validación debería de generar un throw new Exception()
para que el controlador pudiera a través de un try/catch determinar que hacer con el error,
ejemplo :
if ($_FILES[$file]['error'] > 0)
throw new Exception(‘Error: No se ha logrado subir el archivo’);
de hecho eso terminaría el método en curso y ya no se requerirá el return false;
y si fuera así como fuera la mejor manera una actividad mas del controlador seria resolver los posibles problemas generados en Modelo, en el modelo se metería la validación pero en el Controlador el manejo del error.
en el Controlador
try {
$f=new Foto();
$f->save ($_GET[id],”foto”);
$this->getView(“ok”,array(“txt”=>”La Foto Fue Guardada”));
} catch (Exception $e) {
$this->getView(“error”,array(“txt”=>$e->getMessage() ));
}
¿que opinas?
hace 4 meses
Muy Bien tu propuesta :) haz entendido perfectamente, solo para dejar claro esa seria la iteracion completa.
En cuanto a los mensajes de error siempre deben ser enviado al controller, esto porque la salida la sabe es él. Imagina tengo una aplicación que bajo una misma método del modelo me sirve para guardar desde un formulario (html) o bien desde un Web Service (REST), como es de notar las salidas son totalmente distintas pero los posibles mensajes (éxito o fracaso) deben ser los mismo…
creo que me explique bien en el artículo ¿no?…
hace 2 meses
Una de las formas del model que no se comenta es cuando debes popular de 2 entornos diferentes y luego persistirlos a un 3ro. Ejemplo tomar esa info de fotos no de un repositorio fisico sino de una DB y tomar otra información de un ERP y al final persitir este en un Directorio Activo.
En estos escenarios rompemos mucho el esquema de que la logica esta asociada a los procesos de base de datos SQL y vemos que otros entornos nos sirve para persistir la información.
Otro escenario es cuando tu Recovery lo haces de dispositivos electronicos(celulares, centrales telefonicas, etc) y los persiste en DB o porque no NoSQL. Igualmente mucha de lo que te expreso puede ser armarlo como si fuesen entornos de DB, otros tipos de ActiveRecords con “conectores” especializados para realizar estos trabajos.
BTW, puedo continuar con otros escenarios (BI, Emulación de Terminales Mainframe, Dialogar con Brokers Mainframe, etc), al final la cosa es que debemos hacer nuestro controlador limpio de toda la “basura” de resolución y dejarle a una capa model bien ordenada y estructurada que permita hacer llamadas simples y resolver neustras cosas…disculpa si me alargue
hace 2 meses
Muy Bien Zeitan entiendo perfectamente, pero todo lo que expones terminan siendo modelos digamos modelos que interactuan con otros, esto es POO es encapsulamiento, cada objeto de esa capa debe hacer su trabajo (guardarse, eliminarse, actualizar, etc)…
Y llegamos a final del asunto que muchos desconocen y es que lanzan la “lógica” de la aplicación.
De aquí podemos ponernos mas esotéricos con los ejemplos que muy bien haz citado para que quede como referencia, incluso escribir un libro de MVC muy lindo “Aprende MVC con Pipo” (hasta nombre le tengo).
Muchas Gracias por el Comentario…
hace 2 meses
La mala implementación de MVC creo que viene por 2 causas, flojera y chip incrustrado. La flojera/comodidad de agregar mucha logica en el 1er sitio que abrimos el editor y podemos hacer las clases (controller y hasta views) y el chip que Models es Tabla. De alli haz todas las variante que desees.
El libro llamalo mejor “MVC for Lazies using KumbiaPhp”, asi vendes los derechos de uso del nombre xD
Btw te iba apreguntar, kumbia le gusta andar en rieles, no? Veo el esquema de la implementación que llevan es bastante similar a RoR o la implementación de patrones es la misma mejor dicho,
¿van a permitir en algun momento la creación de addons (gemas) y plugins para su framework?
hace 2 meses
jajaja me gusta ese nombre!…
Bueno sobre los rieles, es así los developers de KumbiaPHP son RoRistas y Pythonistas xD.
Sobre los plugin, addons y/o cualquier otro nombre, si esta contemplado solo que hemos evaluado las opciones para que sean realmente plugines y no lo que hacen mucho que son mini-app confundiendo con plugin…
Por ejemplo en nuestro ActiveRecord meteremos behaviors incluso el actual lo soporta, pero ese código es “legacy” así que el nuevo viene mejor pensado desde el punto de vista de diseño…
Pero el ActiveRecord de KumbiaPHP es muy parecido a RoR y la filosofia es la misma “Convención sobre configuración”.
Pero para el manejo de plugin tenemos una idea bien macro que es interesante…
hace 1 mes
saludos cachi, mira mirando la doc de KumbiaPHP veo que en la imagen de MVC que tienen ponen una conexion entre la Vista y el Modelo diciendo que es para obtener el estado del modelo. En mi concepto la vista no debe conocer nada del modelo a no ser que sea usado el patron Observer y no obstante no debe ver nada. Quisiera que me explicaras esa relacion.
hace 1 mes
Un Saludo Adrian, bien la excepción confirma la regla estamos claro que no debe ser asi, sin embargo cuando tiene alto niveles de workflow hay vistas que si (muy pocas) necesiten ir directamente a un modelo solo a pedir datos por ejemplo en KumbiaPHP esto sería un partial, ilustro un poco mas el ejemplo… Imagina un partial que es un menu de usuario, ya el nombre te debe decir que este partial no depende un controller entonces hablamos que el puede consultar un método del modelo usuario se me ocurre $usuario->getMenu($userID)…
En cualquier documentación MVC verás una relación entre las vistas y los modelos, pero esta debe ser observada desde una óptica muy crítica tal como lo estas apreciando.
Te comento que ahorita estoy trabajando en el nuevo manual de KumbiaPHP y estamos corrigiendo muchas cosas que estaban mal a nivel del MVC, explicaciones mas claras, ejemplos mas concisos, etc. ya que todo este trabajo era legacy (heredado) el cual nos ha llevado tiempo corregir pero ya estamos encaminado.
Espero que la explicación con un breve ejemplo hallá sido la propia para aclarar tu duda.
Éxitos!
hace 1 mes
Ok exitos entonces y que viva KumbiaPHP