Download mvc

Document related concepts
no text concepts found
Transcript
Model-View-Controller
 La UI de una aplicación está sujeta a muchos cambios:
 Cambio de UI para diferentes usuarios
 Los cambios en la UI deben ser fáciles aún en runtime
 Diferentes “look and feel ” no deben afectar el núcleo
funcional
 La misma información puede mostrarse en ventanas
diferentes
 Los cambios en los datos subyacentes, deben reflejarse
inmediatamente en todas las vistas
 Conviene separar: procesamiento, entradas y salidas
Model-View-Controller (MVC)
 MVC divide una aplicación UI en:
 Modelo: Contiene el núcleo funcional y datos
 Vista: Muestra información al usuario
 Controlador: Maneja las entradas del usuario
 Vistas+Controladores = UI
 Mecanismo de “Change-Propagation” : Único link entre
Modelo e UI.
La “tríada” de objetos MVC
View
Output
Model
Input
Controller
UI
Dinámica del MVC
1. Una entrada del usuario
es enviada por el SO
al controlador apropiado
V
M
2. El controlador puede
requerir a la Vista que
“tenga” el foco del
evento.
C
Dinámica del MVC
3. Controlador requiere
métodos del Modelo
para cambiar su estado
V
M
4. Modelo cambia su
estado interno
C
Dinámica del MVC
5. Modelo notifica a todas
las Vistas dependientes
que hay datos que se
V
M
modificaron
6. Vistas requieren del
Modelo los valores de los
datos actuales.
C
Dinámica del MVC
7. Modelo notifica a todos
los Controladores
dependientes que hay
V
M
datos que cambiaron.
8. Controlador requiere del
Modelo los valores
actuales de los datos.
C
Dinámica del MVC
9. Controlador informa a
las Vistas si se
deshabilitan algunos
V
M
elementos.
10. Vistas requieren
redibujado
C
Patrón Observer
 MVC es un patrón que puede ser expresado como una
combinación de otros patrones.
 La interacción Modelo-Vista es generalmente descripta
usando el patrón Observer:
 Define una dependencia uno a muchos entre objetos,
de forma tal que cuando uno de ellos (sujeto
Observable) cambia su estado, todos los que dependen
de éste (Observers) son notificados y actualizados
automáticamente.
Patrón Observer
Observers
Un sujeto puede tener cualquier cantidad de observadores
dependientes. Todos los observadores son notificados cuando el
sujeto experimenta un cambio en su estado. En respuesta a ello
cada observador interroga al sujeto para sincronizar su estado con
el de éste.
Java: Observer/Observable
 java.util.Observable (Subject): Cualquier clase que desee
ser observada debe extender esta clase
 métodos para add/delete Observers
 métodos para notify todos los Observers de un cambio
(para indicar que hubo un cambio:setchanged)
Use Vector para almacenar las referencias a los Observers
 java.util.Observer (interface) debe ser implementada por
cualquier clase que quiera actuar como Observer.
 update() en respuesta a notifyObserver()
 Modelo de delegación de eventos: la fuente de eventos es
Observable y los “listeners” de eventos son Observers.
Ejemplo
// Un sujeto a observar !
public class ConcreteSubject extends Observable {
private String name;
private float price;
public ConcreteSubject(String n, float p) {
name = n;
price = p;
System.out.println("ConcreteSubject creado: " + name
+"a
"+ price);}
public setPrice(float p){price=p;//idem para setName
setChanged();//flag para indicar el cambio en
Observable
Ejemplo
// An observer of price changes. (Idem para observar nombre)
public class PriceObserver implements Observer {
private float price;
public PriceObserver() {price = 0;
System.out.println("PriceObserver creado: Precio es " +
price);}
public void update(Observable obj, Object arg) {
if (arg instanceof Float) {price = ((Float)arg).floatValue();
System.out.println("PriceObserver: Precio cambia a " +
Ejemplo
//Test
public class TestObservers {
public static void main(String args[]) {
// Create the Subject and Observers.
ConcreteSubject s = new ConcreteSubject("Corn Pops",
1.29f);
PriceObserver priceObs = new PriceObserver();
s.addObserver(priceObs);//registro del observer con
Observable
s.setPrice(4.57f);
Ejemplo
Salida del programa Test
ConcreteSubject creado: Corn Pops a 1.29
PriceObserver creado: Precio es 0.0
PriceObserver: Precio cambia a 4.57
MVC y Swing
 Swing usa una arquitectura similar a MVC, llamada
Model-Delegate, muy difícil crear un controlador genérico
que no conozca los datos específico de una vista.
 Colapsan Vista y Controlador (UI) en un único objeto
(UI delegate, puesto que la UI se delega a este objeto).
 Se pueden usar múltiples vistas de un mismo modelo.
 Componentes pueden compartir un mismo modelo.
(JScrollBar, JSlider, ProgressBar comparten el
BoundedRangeModel), permitiendo la conectividad
automática entre componentes.
MVC y Swing
View
Model
Controller
Component
UI-delegate
MVC y Swing
MVC y Swing
Modelos en Swing
 En Swing muchos de los modelos son interfaces
 Ej.: ButtonModel, ListModel, TableModel
 Usualmente existe un modelo “por defecto” que se asocia
automáticamente con un componente
 DefaultButtonModel implementa ButtonModel
 Muchas aplicaciones no necesitan preocuparse por ellos
Modelos en Swing
 Casi todos los componentes proveen el API del modelo
directamente. El componente puede ser manipulado sin
interactuar con el modelo para nada.
//Ejemplo de la clase JSlider
public int getValue() {
return getModel().getValue();
}
//Podemos usar lo siguiente y evitar el modelo
JSlider slider = new JSlider();
int value = slider.getValue();
Views & Controllers - Swing
En Swing la expresión “look and feel” (L&F) es común
Look (apariencia) es la Vista
Feel (comportamiento) es el Controlador
Combinar la Vista y el Controlador permite que
que el L&F de un componente sea tratado como una
unidad y por tanto facilita los cambios en la UI.
 Conocido como pluggable look & feel (PLAF), se
puede cambiar la representación visual en tiempo de
ejecución




PLAF
PLAF
 Para cambiar el L&F al de la plataforma nativa del usuario:
try {
UIManager.setLookAndFeel (
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (java.lang.ClassNotFoundException e) {
// No puede cambiar el L&F
}
 Para cambiar a Metal L&F (Java-native L&F)
try {
UIManager.setLookAndFeel (
"javax.swing.plaf.metal.MetalLookAndFeel");
} catch (java.lang.ClassNotFoundException e) {
// Si no puede cambiar el L&F}