Vous êtes sur la page 1sur 30

Federico Peinado www.federicopeinado.

es
Depto. de Ingeniera del Software e Inteligencia Artificial disia.fdi.ucm.es
Facultad de Informtica www.fdi.ucm.es Universidad Complutense de Madrid www.ucm.es

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

En

MVC cada elemento tiene tres partes:

Un modelo que contiene los datos y la funcionalidad de

la aplicacin

Juego ajedrez: estado del tablero, reglas del ajedrez, etc.

Una vista que gestiona como se muestran esos datos Juego ajedrez: ventana que dibuja el tablero, oyentes de eventos, etc. Un controlador que determina que modificaciones hay

que hacer en el modelo cuando se interacciona con la vista. Tambin puede contener algoritmos

Juego ajedrez: control de eventos, algoritmo para pensar las jugadas, etc.

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Es

posible tener diferentes vistas para un mismo modelo Es posible construir nuevas vistas sin necesidad de modificar el modelo subyacente Proporciona un mecanismo de configuracin para componentes complejos mucho ms tratable que el puramente basado en eventos (el modelo puede verse como una representacin estructurada del estado de la interaccin)
Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

El modelo no debe ver a ninguna clase de los otros grupos:


Se podra cambiar de vista y controlador sin tocar el modelo

El controlador debe ver las clases del modelo, pero no de la vista el cambio de vista no afecta al controlador
En algunas variantes de la arquitectura el controlador puede ver a la

vista por si alguna accin del controlador afecta a la vista pero no al modelo (e.g. mensaje de error)

La vista no debe ver las clases del modelo el cambio de modelo no afecta a la vista
En algunas variantes la vista ve al modelo para consultarle

informacin, pero nunca para realizar cambios en l

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Para que la vista se entere de los cambios producidos en el modelo, se utiliza el patrn Observer Cuando se produce un cambio en el modelo (setDatos(datos:TDatos)):

La vista se registra como oyente/observador del modelo

Se llama al mtodo notificarXXXX() Normalmente los mtidos notificarXXXX() son protegidos o privados. notificar() llama al mtodo actualizarXXX() de

Los mtodos actualizar() se encargan de actualizar las

A veces se utilizan otros nombres para actualizarXXXX() como XXXXPerformed()

todos los observadores registrados

respectivas vistas

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Los oyentes se pueden seguir implementando como clases internas de la vista


Dentro de los manejadores se llamarn a mtodos del controlador

Los mtodos notificar y actualizar se pueden desdoblar para distintos tipos de actualizaciones en la vista Conviene separar en 3 paquetes las clases correspondientes a cada parte de la arquitectura

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Para

arrancarlo todo en el mtodo main:

Modelo modelo = new Modelo(); Controlador controlador = new Controlador(modelo); Vista vista = new Vista(controlador); modelo.aadirObservador(vista);

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

Esta arquitectura tiene an ms justificacin si tenemos varias vistas


A travs de los observadores registrados en el modelo se actualizan las distintas

vistas cuando se producen cambios en el modelo. modelo.aadirObservador(vista1); modelo.aadirObservador(vista2);

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

10

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

11

public class Aplicacin { public static void main(String args[]) { Modelo modelo = new Modelo(); Controlador controlador = new Controlador(modelo); Vista1 vista1 = new Vista1(controlador); Vista2 vista2 = new Vista2(controlador);
Vista1 otraVista1 = new Vista1(controlador); Vista2 otraVista2 = new Vista2(controlador); modelo.aadirObservador(vista1); modelo.aadirObservador(vista2); modelo.aadirObservador(otraVista1); modelo.aadirObservador(otraVista2);

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

12

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

13

Interface Observer (java.util)


void update (Observable observable, Object o)

Class Observable (java.util)


Tiene un flag interno que indica si el objeto observable ha

cambiado o no Mtodos:

void addObserver(Observer obs): Aade un observador a la lista void deleteObserver(Observer obs): Quita un observador de la lista void setChanged(): Marca el objeto observable como cambiado void notifyObservers(Object o): Si el objeto observable ha cambiado, llama al mtodo update de todos los observadores. Vuelve a dejar el objeto observable como no cambiado

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

14

Las vistas deben implementar el interfaz Observer


Por tanto, deben implementar el mtodo update

El modelo debe heredar de Observable


No necesita un atributo con la lista de observadores No necesita implementar los mtodos para aadir y

eliminar observadores No necesita implementar ningn mtodo notificar Cuando se produzca un cambio en el modelo (setDatos(datos:TDatos)) hay que:

Actualizar el modelo Indicar que el modelo ha cambiado llamando a setChanged() Notificar a todos los observadores registrados el cambio producido en el modelo llamando a notifyObservers(Object o)
Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

15

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

16

public class Aplicacin { public static void main(String args[]) {


Modelo modelo = new Modelo();

Controlador controlador = new Controlador(modelo);


Vista1 vista1 = new Vista1(controlador); Vista2 vista2 = new Vista2(controlador); modelo.addObserver(vista1); modelo.addObserver(vista2);

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

17

public class Modelo extends Observable {


private int valor; // Datos public void setValor(int nuevoValor) { valor = nuevoValor; // indica que el modelo ha cambiado this.setChanged(); this.notifyObservers(new Integer(valor)); }

}
Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

18

public class Controlador {


private Modelo modelo; public Controlador (Modelo unModelo){ modelo = unModelo; } public void fijarValor(int valor) throws ExcepcionRango {

if ((valor > 16) || (valor < 0)) throw new ExcepcionRango();


} modelo.setValor(valor);

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

19

public class Vista1 extends Jframe implements Observer {


private Controlador controlador; (...) public Vista1(Controlador unControlador){ controlador = unControlador; configurarComponentes(); configurarManejadoresEventos(); } public void configurarManejadoresEventos() { //Crea Oyentes locales de la interfaz //Los oyentes invocan mtodos del controlador }

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

20

public void update(Observable o, Object valor){ //Actualizacin de la interfaz } public class OyenteVista1 implements ActionListener {

public void actionPerformed(ActionEvent e){ //Procesamiento del evento (...)


try { controlador.fijarValor(valor); } catch (ExcepcinRango e) { JOptionPane.showMessageDialog(null, e); }

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

21

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

22

Existen mltiples variaciones e interpretaciones


Lo importante es separar los tres elementos

Problemas tpicos:
El usuario interacta con el controlador?

El usuario puede considerarse parte de la vista Un servidor remoto puede ser parte de la vista
El controlador enva informacin a la vista?

Puede interesar enviar informacin directamente a la vista desde el controlador (mostrar mensajes de error) Pero entonces el controlador necesita una lista de vistas
La vista accede al modelo para preguntar el estado?

La vista puede tener una replica del modelo y actualizarla Los eventos pueden llevar una referencia del estado La vista puede tener una referencia al modelo para hacerle preguntas
Pero nunca para cambiarlo!

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

23

Modelo (datos)

Vista Modelo m Control c

Controlador Modelo m Vista v

Interfaces claros!

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

24

Modelo (datos)

Vista Modelo m Control c

Controlador Modelo m Vista v


El controlador acta de mediador en todas las comunicaciones

Interfaces claros!

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

25

En Swing se utiliza una adaptacin de esta arquitectura de modo que la vista y el controlador se agrupan en el componente (Delegado) pero el modelo se mantiene separado permitiendo comportamientos muy sofisticados
Por ejemplo, como los modelos gestionan y almacenan los datos existe la

posibilidad de compartir un mismo modelo entre varios componentes. Cada uno de los componentes puede modificar el modelo y dicha modificacin se reflejar de forma automtica en el resto de los componentes que comparten dicho modelo Estos modelos de datos son especialmente importantes en los componentes que trabajan con texto y en las listas

El modelo se consulta y actualiza con mtodos get<Model> / set<Model> (donde <Model> depende del tipo de componente) El delegado se consulta/actualiza con los mtodos getUI / setUI

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

26

Componente Swing

Vista

Modelo

Controlador delegado

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

27

public class ModeloCompartido { JTextArea areaTexto1, areaTexto2; JFrame ventana; Document documento; public ModeloCompartido(String titulo){ ventana = new JFrame(titulo); Container panelContenido = ventana.getContentPane(); areaTexto1= new JTextArea(10,100); documento=areaTexto1.getDocument(); areaTexto2= new JTextArea(documento); areaTexto2.setColumns(100); areaTexto2.setRows(10); panelContenido.setLayout(new BoxLayout(panelContenido, BoxLayout.Y_AXIS)); panelContenido.add(new JScrollPane(areaTexto1)); panelContenido.add(Box.createGlue()); panelContenido.add(new JScrollPane(areaTexto2)); panelContenido.add(Box.createGlue()); ventana.setSize(500, 300); ventana.setVisible(true); } public static void main(String args[]) { ModeloCompartido aplicacion = new ModeloCompartido("Prueba documento compartido"); } }//ModeloDocumentoCompartido

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

28

Laboratorio de Programacin de Sistemas Patrn Modelo-Vista-Controlador

29

Federico Peinado www.federicopeinado.es

Vous aimerez peut-être aussi