Patrones de diseño: Observer

Con este patrón de diseño se puede implementar vista-controlador.

Este patrón de diseño resuelve el problema de actualizar un objeto cuando otro cambie de estado, estos objetos pueden ser componentes dentro de un frame o incluso otros frames.

Existe un observado (extends Observable) y un observador (implements Observer), el observado notifica al observador cuando cambia de estado, y el observador hace lo que crea conveninte con update(Observable obs, Object o).
Hay formas mucho más sencillas de hacer esto, pero aquí hay un ejemplo, el concepto es sencillo.

package voyerismo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import javax.swing.JComboBox;

/**
 *
 * @author fal
 *
 * Esta clase hereda de Observable, servirá para el primer combobox.
 * Es como un exhibicionista
 *
 */
public class Observado extends Observable{

	private JComboBox jcombobox = null;

	public Observado(){
		String numeros[] = {"-","UNO", "DOS", "TRES","CUATRO"};
		jcombobox = new JComboBox(numeros);

		jcombobox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				switch(jcombobox.getSelectedIndex() ){
				//En cada case se cambia el estado, y se notifica a los observadores
				case 1:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 2:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 3:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 4:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				default:
					setChanged();
					notifyObservers("");
				}

			}

		});

	}

	/**
	 *  Para obtener el combobox
	 * @return combobox El combobox que será espiado
	 */
	public JComboBox getCombobox(){
		return this.jcombobox;
	}

}

package voyerismo;

import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;

/**
 *
 * @author fal
 *
 * Esta clase es la que observa al observado, es como el que estará espiando
 * al combobox de la clase <code>Observado</code>
 *
 */

public class Observador implements Observer{

	private JComboBox combo = null;
	private DefaultComboBoxModel modeloLight = null;
	private String[] unos = { "Uno", "1", "i", "a", "I" };
	private String[] doses = { "Dos", "2", "ii", "b", "II" };
	private String[] treses = { "Tres", "3", "iii", "c", "III" };
	private String[] cuatros = { "Cuatro", "4", "iv", "d", "IV" };

	public Observador(){
		modeloLight = new DefaultComboBoxModel();
		combo = new JComboBox(modeloLight);
		combo.setEnabled(false);

	}

	/**
	 * Aqui se implementa el método de la interfaz <code>Observer</code>
	 * el observado le notifica a éste para que éste haga lo tenga que hacer.
	 *
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
	 *
	 */
	public void update(Observable observado, Object selectedItem) {
		if(observado != null && (observado instanceof Observado) ){
			if(selectedItem != null){
			String str = selectedItem.toString();
			if(str.equals("UNO") ){
				enfria(unos);
				combo.setEnabled(true);
			}else if(str.equals("DOS") ){
				enfria(doses);
				combo.setEnabled(true);
			}else if(str.equals("TRES") ){
				enfria(treses);
				combo.setEnabled(true);
			}else if(str.equals("CUATRO") ){
				enfria(cuatros);
				combo.setEnabled(true);
			}else{
				enfria(new String[] {});
				combo.setEnabled(false);
			}		
		}

	}

	public JComboBox getCombobox(){
		return this.combo;
	}

	/**
	 * Cambia el modelo(le hace un update)
	 * @param strings
	 */
	private void enfria(String[] strings){
		modeloLight.removeAllElements();
		for (String string : strings) {
			modeloLight.addElement(string);
		}
	}	

}
package voyerismo;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {

	public static void main(String args[]) {
		JFrame frame = new JFrame();
		JPanel panel = new JPanel();
		Observado observado = new Observado();
		Observador observador = new Observador();

		//Se agregan los observadores al observado
		observado.addObserver(observador);

		JComboBox combo1 = observado.getCombobox();
		JComboBox combo2 = observador.getCombobox();

		panel.add(new JLabel("Observado") );
		panel.add(combo1);
		panel.add(new JLabel("ObservadoR") );
		panel.add(combo2);

		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.add(panel);
		frame.setTitle("Observado y observador");
		frame.setSize(400, 100);
		frame.setVisible(true);

	}

}

Véase también:

http://en.wikipedia.org/wiki/Observer_pattern
http://www.lcc.uma.es/~pacog/apuntes/poo/Tema4-2.pdf
http://www.patterndepot.com/put/8/observer.pdf
http://java.sun.com/j2se/1.5.0/docs/api/java/util/class-use/Observable.html

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s