Herramientas de usuario

Herramientas del sitio


bloque4:mvc

Patrón Modelo-Vista-Controlador

Cuando se diseña una aplicacion aplicando el patrón de diseño modelo-vista-controlador, se persigue separar la aplicación en 3 capas distintas diferenciadas.

  • La vista hace referencia a la ventana principal de la aplicación, la que contiene la mayoría de los elementos sobre los que el usuario va a interactuar. En MVC, la vista solo contiene el código referente a la construcción y organización de los componentes gráficos. Esta clase no contiene ningún manejador de eventos ni ningun código que haga alguna operación. No tiene ninguna interacción con el modelo.
  • El modelo es la capa que contiene los datos de la aplicación y los gestiona. Es la que se encarga de satisfacer las peticiones del usuario que se indican en la vista. Recordemos que el usuario solo interactua con la vista. El modelo contiene todos los métodos para realizar las operaciones de nuestra aplicación. Dar de alta elementos, eliminar, buscar, guardar, cargar, etc. No tiene ninguna constancia de la vista.
  • El controlador es la capa que comunica a las otras dos. Al llamar a su constructor, se le pasar como parámetro una instancia de la vista, y otra del modelo. El controlador es quien tiene implementados los manejadores de eventos y se los añade a los componentes de la vista indicados, y también es quien ejecuta las operaciones del modelo en respuesta a esos eventos.

Resulta aconsejable que al menos las clases que representan el modelo, la vista y el controlador estén dentro del mismo paquete (package).

Vista

Todos los componentes gráficos (botones que se puedan pulsar, campos de texto de los que obtener datos, cajas de texto, etc) que quiera gestionar desde el controlador deben tener visibilidad (default).

public class Vista extends JFrame {
 
    JPanel contentPane;
    JTextField textNombre;
    JTextField textApellidos;
    ... 
    //Todos los componentes swing que gestione desde el controlador
 
 
    public Vista(){
       initComponents();
    } 
 
    public void initComponentes(){
        setResizable(false);
        setTitle("Mi Aplicacion");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ... 
        //resto del código generado por WindowBuilder
 
        set visible(true);
    }
}

Modelo

El modelo es la clase que maneja los datos de la aplicación y permite las operaciones. Los puede obtener desde un fichero o desde una base de datos. Puede cargar esos datos en una estructura como el ArrayList o leerlos cada vez. No tiene ningún conocimiento ni interacción con la vista, y devuelve y recibe los datos tal cual se los pide el controlador.

public class Modelo{
   //Lista con los datos que gestiona mi aplicación
   private ArrayList<Persona> listaPersonas;
   ...
 
   public Modelo(){
      listaPersonas = new ArrayList<Persona>;
   }
 
 
   //Métodos para acceder a los datos
   public ArrayList<Persona> obtenerPersonas(){
      return listaPersonas;
   }
 
 
   //Operaciones sobre los datos
   public void altaPersona(String nombre, int edad){
       Persona nuevaPersona = new Persona(nombre, edad);
       listaPersonas.add(nuevaPersona);
   }
 
   ...
 
}

Controlador

La clase Controlador añade los manejadores de eventos (listeners) a cada elemento de la vista que lo provoque. En el momento de añadir los listeners también los creamos, o sea generamos el código de respuesta a ese evento. Qué pasa cuando se pulsa un botón.

public class Controlador{
    private Vista vista;
    private Modelo modelo;
 
    //Constructor recibe instancia de la vista y del modelo
    public Controlador(Vista vista, Modelo modelo){
        this.vista = vista;
        this.modelo = modelo;
 
        initEventHandlers();
    }
 
    //Método para añadir los listeners a los elementos que las generan (botones)
    public void initEventHandlers(){
 
       vista.btnAceptar.addActionListener(new ActionListener() {
	     public void actionPerformed(ActionEvent arg0) {
                  ...
                  //Código que quiero que ocurra al pulsar el botón de aceptar   
             }
       });
 
       //Añadir tantos manejadores de eventos como acciones pueda realizar
       ...
    }
}

Controlador implementando interfaces

Otra forma mucho más elegante de implementar la clase Controlador es haciendo que trabaje como Listener de ciertos tipos de eventos. Para eso haremos que la clase implemente las distintas interfaces de cada tipo de evento. En el caso siguiente implementamos la interfaz ActionListener, que ofrece soporte para los eventos de tipo ActionEvent.

public class Controlador implements ActionListener{
    private Vista vista;
    private Modelo modelo;
 
    //Constructor recibe instancia de la vista y del modelo
    public Controlador(Vista vista, Modelo modelo){
        this.vista = vista;
        this.modelo = modelo;
 
        asociarListeners(this);
    }
 
    //Metodo que asocia esta clase como listener de los botones
    public void asociarListeners(ActionListener listener){
       vista.botonNuevo.addActionListener(listener);
       vista.botonEliminar.addActionListener(listener);
    }
 
    //Metodo que la interface ActionListener obliga a implementar
    //Es el encargado de gestionar los eventos ActionEvent de los botones
    @Override
    public void actionPerformed(ActionEvent evt) {
       String comando = evt.getActionCommand();
 
       switch(comando){
          case "nuevo":
             //codigo para el boton nuevo
             break;
          case "eliminar":
             //codigo para el boton eliminar
             break;
 
          ...
       }
    }
 
}

Lanzar la aplicación

Por último desde una clase con un método main lanzo la aplicación, creando una isntancia de cada clase.

public class Principal(){
    public static void main(String[] args){
        Vista vista = new Vista();
        Modelo modelo = new Modelo();
        Controlador controlador = new Controlador(vista, modelo);
    }
}

© 2020 Fernando Valdeón

bloque4/mvc.txt · Última modificación: 04/01/2019 13:13 (editor externo)