jairogarcíarincón
Según la Wikipedia, Modelo-Vista-Controlador (MVC):
"Es un patrón de arquitectura de software, que separa los datos y la lógica de negocio de una aplicación de su representación y el módulo encargado de gestionar los eventos y las comunicaciones. Para ello MVC propone la construcción de tres componentes distintos que son el modelo, la vista y el controlador, es decir, por un lado define componentes para la representación de la información, y por otro lado para la interacción del usuario. Este patrón de arquitectura de software se basa en las ideas de reutilización de código y la separación de conceptos, características que buscan facilitar la tarea de desarrollo de aplicaciones y su posterior mantenimiento."
Modelo: Es la representación de la información con la cual el sistema opera, por lo tanto gestiona todos los accesos a dicha información, tanto consultas como actualizaciones, implementando también los privilegios de acceso que se hayan descrito en las especificaciones de la aplicación (lógica de negocio).- Controlador: Responde a eventos (usualmente acciones del usuario) e invoca peticiones al 'modelo' cuando se hace alguna solicitud sobre la información (por ejemplo, editar un documento o un registro en una base de datos). También puede enviar comandos a su 'vista' asociada si se solicita un cambio en la forma en que se presenta el 'modelo' (por ejemplo, desplazamiento o scroll por un documento o por los diferentes registros de una base de datos), por tanto se podría decir que el 'controlador' hace de intermediario entre la 'vista' y el 'modelo'.
- Vista: Presenta el 'modelo' (información y lógica de negocio) en un formato adecuado para interactuar (usualmente la interfaz de usuario), por tanto requiere de dicho 'modelo' la información que debe representar como salida.
A partir de estas indicaciones, vamos a transformar nuestro proyecto de coches para adaptarlo al patrón MVC. Además, le añadiremos dos vistas diferentes, el listado de todos los coches y los datos de un coche concreto.
Para facilitar el aprendizaje, partiremos del ejemplo Instanciar una clase externa , más sencillo al tener una sola clase y ninguna herencia.
Los primeros pasos que tendríamos que seguir serían los siguientes:
- Crear 3 carpetas llamadas controller, model y view, y un archivo index.php en el directorio raíz que se encargue de gestionar la aplicación y las diferentes peticiones de rutas.
- Dentro de la carpeta model haremos una copia de nuestro modelo de clase Coche.
- Dentro de la carpeta controller crearemos la clase CocheController con un método público index() cuya función será recoger todos los objetos de clase Coche y mostrarlos como una lista a través de un archivo de vista (que tendremos que requerir)
- Como de momento no estamos usando persistencia de datos, añadiremos un método construct() a ClaseController que inicialice un array con 5 coches.
- El método index() de ClaseController recogerá esa variable de coches, la asignará a una variable y requerirá la vista de listado (en view/index.php).
- La vista de listado recorrerá el array mediante un foreach y mostrará los datos.
- Por último, el archivo raíz index.php requerirá las clases necesarias (Coche y CocheController), instanciará un nuevo controlador y ejecutara su método index().
Archivo controller/CocheController.php:
<?php
class CocheController
{
var $coches;
function __construct()
{
$this->coches = [
1 => new Coche("Wolkswagen","Polo","negro","Rebeca"),
2 => new Coche("Toyota","Corolla","verde","Marcos"),
3 => new Coche("Skoda","Octavia","gris","Mario"),
4 => new Coche("Kia","Niro","azul","Jairo")
];
}
public function index(){
//Asigno los coches a una variable que estará esperando la vista
$rowset = $this->coches;
//Le paso los datos a la vista
require("view/index.php");
}
}
Archivo model/Coche.php:
<?php
class Coche
{
//Variables o atributos
var $marca;
var $modelo;
var $color;
var $propietario;
function __construct($miMarca,$miModelo,$miColor,$miPropietario){
$this->marca = $miMarca;
$this->modelo = $miModelo;
$this->color = $miColor;
$this->propietario = $miPropietario;
}
//Funciones o métodos
function setMarca($miMarca){
$this->marca = $miMarca;
}
function getMarca(){
return $this->marca;
}
function setModelo($miModelo){
$this->modelo = $miModelo;
}
function getModelo(){
return $this->modelo;
}
function setColor($miColor){
$this->color = $miColor;
}
function getColor(){
return $this->color;
}
function setPropietario($miPropietario){
$this->propietario = $miPropietario;
}
function getPropietario(){
return $this->propietario;
}
}
Archivo view/index.php:
<style>
th{
width: 8rem;
text-align: left;
border-bottom: 1px solid black;
}
td{
width: 8rem;
}
</style>
<h1>Ejemplo 5: Listado de coches</h1>
<table>
<tr>
<th>Marca</th>
<th>Modelo</th>
<th>Color</th>
<th>Propietario</th>
</tr>
<?php foreach ($rowset as $row): ?>
<tr>
<td><?php echo $row->marca ?></td>
<td><?php echo $row->modelo ?></td>
<td><?php echo $row->color ?></td>
<d><?php echo $row->propietario ?></td>
</tr>
<?php endforeach; ?>
</table>
Archivo index.php:
<?php
//Incluyo los archivos necesarios
require("./model/Coche.php");
require("./controller/CocheController.php");
//Instancio el controlador
$controller = new CocheController;
//Ejecuto el método
$controller->index();
Antes de terminar el ejemplo, vamos a avanzar algunas conclusiones:
- Los controladores nos permiten separar las acciones (métodos que suelen generar vistas) de los modelos, y además los utilizamos para llamar a las vistas.
- Los modelos contienen toda la información relativa a los datos con los que estamos trabajando: atributos y métodos.
- Las vistas recogen los datos del controlador y los muestran al usuario.
- En el archivo raíz index.php es donde se requieren todas las clases, se extrae la ruta de la barra de direcciones y se deciden tanto el controlador como la acción que dicho controlador debe ejecutar, por lo que todas las rutas de nuestro sitio web deben necesariamente pasar por dicho archivo.
Esto último quizá no quede tan claro dado el ejemplo, pero es la clave de los desarrollos con modelo MVC y es utilziado por la mayoría de los frameworks actuales.
Para entenderlo mejor, vamos a suponer ahora que además queremos incorporar una nueva vista, llamada ver, que nos permita mostrar los datos de uno de los coches a partir de su clave.
Para conseguirlo, debemos llevar a cabo las siguientes acciones:
- Crear el archivo view/ver.php que permita mostrar los datos del coche.
- Escribir dentro de CocheController la acción ver() que recoja la clave del coche, asigne los datos de ese coche a una variable y se los pase a la vista anterior.
- Modificar el archivo raíz index.php para que extraiga la ruta de la barra de direcciones y decida tanto el controlador como la acción a ejecutar.
- Si una vez hecho lo anterior en la barra de direcciones del navegador después de index.php introducimos /ver/2 debería mostrarnos la información del coche con clave 2.
Archivo view/ver.php
<style>
th{
width: 8rem;
text-align: left;
border-bottom: 1px solid black;
}
td{
width: 8rem;
}
</style>
<h1>Ejemplo 6: Vista de coche</h1>
<table>
<tr>
<th>Marca</th>
<th>Modelo</th>
<th>Color</th>
<th>Propietario</th>
</tr>
<tr>
<td><?php echo $row->marca ?></td>
<td><?php echo $row->modelo ?></td>
<td><?php echo $row->color ?></td>
<d><?php echo $row->propietario ?></td>
</tr>
</table>
Método añadido al archivo controller/CocheController.php
public function ver($id){
if (array_key_exists($id,$this->coches)){
//Si el elemento está en el array, lo muestro
$row = $this->coches[$id];
require("view/ver.php");
}
else{
//Llamo al método por defecto del controlador
$this->index();
}
}
Archivo raíz index.php
<?php
//Incluyo los archivos necesarios
require("./model/Coche.php");
require("./controller/CocheController.php");
//Instancio el controlador
$controller = new CocheController;
//Ruta de la home
$home = "/formacion/poo/ejemplo6/index.php/";
//Quito la home de la ruta de la barra de direcciones
$ruta = str_replace($home, "", $_SERVER["REQUEST_URI"]);
//Creo el array de ruta (filtrando los vacíos)
$array_ruta = array_filter(explode("/", $ruta));
//Decido la ruta en función de los elementos del array
if (isset($array_ruta[0]) && $array_ruta[0] == "ver" && is_numeric($array_ruta[1])){
//Llamo al método ver pasándole la clave que me están pidiendo
$controller->ver($array_ruta[1]);
}
else{
//Llamo al método por defecto del controlador
$controller->index();
}
Ejercicio propuesto 5
- Modifica el Ejercicio 4 para adaptarlo al patrón MVC.
- Genera vistas tanto de listado como de ver y de editar, siendo esta última un formulario que permita modificar los datos de cada contacto (sin funcionalidad).
- Añade enlaces en la vista de listado para llegar a dichas vistas sin tener que escribir la ruta en el navegador
Publicado el 21 de Noviembre de 2024