in

Diseño de aplicaciones Java SE con MVC

a common mvc implementation

¿Qué es Model-View-Controller (MVC)?

Si ha programado con bibliotecas de interfaz gráfica de usuario (GUI) en los últimos 10 años, es probable que se haya encontrado con el diseño modelo-vista-controlador (MVC). MVC fue introducido por primera vez por Trygve Reenskaug, desarrollador de Smalltalk en el Xerox Palo Alto Research Center en 1979, y ayuda a desacoplar el acceso a los datos y la lógica empresarial de la forma en que se muestran al usuario. Más precisamente, MVC se puede dividir en tres elementos:

  • Modelo – El modelo representa los datos y las reglas que rigen el acceso y las actualizaciones de estos datos. En el software empresarial, un modelo a menudo sirve como una aproximación de software a un proceso del mundo real.
  • Vista – La vista muestra el contenido de un modelo. Especifica exactamente cómo se deben presentar los datos del modelo. Si los datos del modelo cambian, la vista debe actualizar su presentación según sea necesario. Esto se puede lograr utilizando un modelo de empuje, en el que la vista se registra con el modelo para notificaciones de cambio, o un modelo de tracción, en el que la vista es responsable de llamar al modelo cuando necesita recuperar los datos más actuales.
  • Controlador – El controlador traduce las interacciones del usuario con la vista en acciones que realizará el modelo. En un cliente GUI independiente, las interacciones del usuario pueden ser clics en botones o selecciones de menú, mientras que en una aplicación web empresarial, aparecen como GET y POST Solicitudes HTTP. Dependiendo del contexto, un controlador también puede seleccionar una nueva vista, por ejemplo, una página web de resultados, para presentarla al usuario.

a common mvc implementation

Figura 1. Una implementación común de MVC

Interacción entre componentes MVC

Esta sección examinará más de cerca una forma de implementar la Figura 1 en el contexto de una aplicación en el Plataforma Java, edición estándar 6 (Java SE 6). Una vez que se crean instancias de los objetos de modelo, vista y controlador, ocurre lo siguiente:

  1. La vista se registra como oyente en el modelo. Cualquier cambio en los datos subyacentes del modelo resulta inmediatamente en una notificación de cambio de difusión, que recibe la vista. Este es un ejemplo del modelo push descrito anteriormente. Tenga en cuenta que el modelo no conoce la vista o el controlador; simplemente transmite notificaciones de cambio a todos los oyentes interesados.
  2. El controlador está vinculado a la vista. Por lo general, esto significa que cualquier acción del usuario que se realice en la vista invocará un método de escucha registrado en la clase de controlador.
  3. El controlador recibe una referencia al modelo subyacente.

Una vez que un usuario interactúa con la vista, ocurren las siguientes acciones:

  1. La vista reconoce que se ha producido una acción de la GUI, por ejemplo, presionar un botón o arrastrar una barra de desplazamiento, utilizando un método de escucha que está registrado para ser llamado cuando se produzca dicha acción.
  2. La vista llama al método apropiado en el controlador.
  3. El controlador accede al modelo, posiblemente actualizándolo de una manera apropiada a la acción del usuario.
  4. Si el modelo ha sido alterado, notifica a los oyentes interesados, como la vista, del cambio. En algunas arquitecturas, el controlador también puede ser responsable de actualizar la vista. Esto es común en las aplicaciones empresariales basadas en tecnología Java.

La figura 2 muestra esta interacción con más detalle.

a java se application using mvc

Figura 2. Una aplicación Java SE que usa MVC

Como se mencionó anteriormente en este artículo, el modelo no lleva una referencia a la vista, sino que utiliza un modelo de notificación de eventos para notificar a las partes interesadas de un cambio. Una de las consecuencias de este poderoso diseño es que muchas vistas pueden tener el mismo modelo subyacente. Cuando ocurre un cambio en el modelo de datos, cada vista es notificada por un evento de cambio de propiedad y puede actualizarse en consecuencia. Por ejemplo, la Figura 3 muestra dos vistas que utilizan el mismo modelo de datos.

multiple views using the same model

Figura 3. Varias vistas usando el mismo modelo

Modificar el diseño de MVC

Una implementación más reciente del diseño MVC coloca el controlador entre el modelo y la vista. Este diseño, que es común en el marco de Apple Cocoa, se muestra en la Figura 4.

an mvc design placing the controller between the model and the view

Figura 4. Un diseño MVC que coloca el controlador entre el modelo y la vista

La principal diferencia entre este diseño y la versión más tradicional de MVC es que las notificaciones de cambios de estado en los objetos del modelo se comunican a la vista. mediante el controlador. Por lo tanto, el controlador media el flujo de datos entre el modelo y los objetos de vista en ambas direcciones. Ver objetos, como siempre, use el controlador para traducir las acciones del usuario en actualizaciones de propiedades en el modelo. Además, los cambios en el estado del modelo se comunican para ver los objetos a través de los objetos del controlador de una aplicación.

Por lo tanto, cuando se crean instancias de los tres componentes, la vista y el modelo se registrarán con el controlador. Una vez que un usuario interactúa con la vista, los eventos son casi idénticos:

  1. La vista reconoce que se ha producido una acción de la GUI, por ejemplo, presionar un botón o arrastrar una barra de desplazamiento, utilizando un método de escucha que está registrado para ser llamado cuando se produzca dicha acción.
  2. La vista llama al método apropiado en el controlador.
  3. El controlador accede al modelo, posiblemente actualizándolo de una manera apropiada a la acción del usuario.
  4. Si el modelo ha sido alterado, notifica a los oyentes interesados ​​del cambio. Sin embargo, en este caso, el cambio se envía al controlador.

¿Por qué adoptar este diseño? El uso de este MVC modificado ayuda a desacoplar más completamente el modelo de la vista. En este caso, el controlador puede dictar las propiedades del modelo que espera encontrar en uno o más modelos registrados con el controlador. Además, también puede proporcionar los métodos que afectan los cambios de propiedad del modelo para una o más vistas que están registradas con él.

Usando el MVC modificado

Esta sección del artículo le muestra cómo poner en práctica este diseño, comenzando con el modelo. Suponga que desea pintar un texto utilizando un modelo de visualización simple con cinco propiedades. El ejemplo de código 1 muestra un componente simple que puede utilizar para crear dicho modelo.

Ejemplo de código 1


public class TextElementModel extends AbstractModel
{

    private String text;
    private Font font;
    private Integer x;
    private Integer y;
    private Integer opacity;
    private Integer rotation;


    /**
     * Provides the means to set or reset the model to
     * a default state
     */
    public void initDefault() {

        setOpacity(89);
        setRotation(0);
        setText("Sample Text");
        setFont(new Font("Arial", Font.BOLD, 24));
        setX(50);
        setY(50);

    }

    //  Accessors


    public String getText() {
        return text;
    }

    public void setText(String text) {

        String oldText = this.text;
        this.text = text;

        firePropertyChange(
            DefaultController.ELEMENT_TEXT_PROPERTY,
            oldText, text);
    }

    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {

        Font oldFont = this.font;
        this.font = font;

        firePropertyChange(
            DefaultController.ELEMENT_FONT_PROPERTY,
            oldFont, font);
    }

    //  The remaining accessors for properties are omitted.

}

Tenga en cuenta que el resto de los descriptores de acceso siguen el modelo estándar de JavaBeans, aunque se omiten en el ejemplo de código 1. Como referencia, el ejemplo de código 2 muestra el AbstractModel clase, que simplemente usa la javax.beans.PropertyChangeSupport class para registrar, cancelar el registro y notificar a los oyentes interesados ​​sobre cambios en el modelo.

Ejemplo de código 2


public abstract class AbstractModel
{

    protected PropertyChangeSupport propertyChangeSupport;

    public AbstractModel()
    {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }

    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }


}

El controlador

Entre el modelo y la vista se encuentra el controlador. Primero, eche un vistazo al código de la superclase del controlador abstracto, como se muestra en el Ejemplo de código 3.

Ejemplo de código 3


public abstract class AbstractController implements PropertyChangeListener {

    private ArrayList<abstractviewpanel> registeredViews;
    private ArrayList<abstractmodel> registeredModels;

    public AbstractController() {
        registeredViews = new ArrayList<abstractviewpanel>();
        registeredModels = new ArrayList<abstractmodel>();
    }


    public void addModel(AbstractModel model) {
        registeredModels.add(model);
        model.addPropertyChangeListener(this);
    }

    public void removeModel(AbstractModel model) {
        registeredModels.remove(model);
        model.removePropertyChangeListener(this);
    }

    public void addView(AbstractViewPanel view) {
        registeredViews.add(view);
    }

    public void removeView(AbstractViewPanel view) {
        registeredViews.remove(view);
    }


    //  Use this to observe property changes from registered models
    //  and propagate them on to all the views.


    public void propertyChange(PropertyChangeEvent evt) {

        for (AbstractViewPanel view: registeredViews) {
            view.modelPropertyChange(evt);
        }
    }


    /**
     * This is a convenience method that subclasses can call upon
     * to fire property changes back to the models. This method
     * uses reflection to inspect each of the model classes
     * to determine whether it is the owner of the property
     * in question. If it isn't, a NoSuchMethodException is thrown,
     * which the method ignores.
     *
     * @param propertyName = The name of the property.
     * @param newValue = An object that represents the new value
     * of the property.
     */
    protected void setModelProperty(String propertyName, Object newValue) {

        for (AbstractModel model: registeredModels) {
            try {

                Method method = model.getClass().
                    getMethod("set"+propertyName, new Class[] {
                                                      newValue.getClass()
                                                  }


                             );
                method.invoke(model, newValue);

            } catch (Exception ex) {
                //  Handle exception.
            }
        }
    }


}

los AbstractController la clase contiene dos ArrayList objetos, que se utilizan para realizar un seguimiento de los modelos y vistas que se registran. Tenga en cuenta que siempre que se registra un modelo, el controlador también se registra a sí mismo como un oyente de cambio de propiedad en el modelo. De esta forma, cada vez que un modelo cambia de estado, el propertyChange() se llama al método y el controlador pasará este evento a las vistas apropiadas.

El método final, setModelProperty(), emplea algo de magia para hacer su trabajo. Para mantener el …

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

0lWxM0xTG7v4XFlPH

Big Data: sus beneficios, desafíos y futuro

Tipo de JavaScript