2012-09-17 29 views
6

Como sé en la implementación estándar de la MVC pasamos el Controlador y el Modelo a la VistaMVC - ¿Necesito usar el Controlador en la Vista?

Pero estoy un poco en desacuerdo con esta idea. No quiero que mi vista sepa sobre el controlador y el modelo (oh no, tal vez a veces vea el modelo de necesidades, pero estoy seguro de que puede vivir sin conocimiento del controlador)

En mi opinión, el controlador debe administrar Vista y modelo, y el Modelo no necesita saber sobre el controlador y la vista; view no necesita saber el controlador (no excluyo el modelo porque algunas implementaciones de vistas deben conocer el modelo para escuchar los cambios en el modelo). Entonces mi idea es que la vista no necesita saber sobre el controlador.

1. Aquí está un ejemplo:

public class MyView implements ButtonClickListener { 

    private Controller myController; 
    private Button myButton; 

    // I commented out the model because we dont need it now 
    // we are talking about using controller in the view 

    public MyView(Controller c/*, Model m*/) { 
     myController = c; 
     myButton  = new Button(); // lets say that it is "register" button 
     myButton.setOnButtonClickListener(this); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    @Override 
    public void onClick() { 
     myController.tellToModelToDoSomething(); 
    } 

} 

y regulador:

public MyController implements Controller { 

    private Model model; 
    private View view; 

    public MyController(Model model) { 

      this.model = model; 
      this.view = new MyView(this); 

    } 

    public void tellToModelToDoSomething() { 
      model.doSomeActions(); 
    } 


} 

2. Y ahora qué es lo que veo esta aplicación sin pasar por el controlador:

Mi visión:

public class MyView { 

    private Button myButton; 

    public MyView() { 
     myButton = new Button(); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    public void setOnRegisterButtonClick(final Command command) { 
     myButton.setOnButtonClickListener(new ButtonClickListener() { 
          @Override 
          public void onClick() { 
           command.execute(); 
          } 
         }); 
    } 

} 

"Comando" Interfaz:

public interface Command { 

    void execute(/*also can handle extra params*/); 

} 

y regulador:

public MyController implements Controller { 

private Model model; 
private View view; 

public MyController(Model model) { 

     this.model = model; 
     this.view = new MyView(); 

     view.setOnRegisterButtonClick(command); 

} 

public void tellToModelToDoSomething() { 
     model.doSomeActions(); 
} 

private Command command = new Command() { 

    public void execute() { 
      tellToModelToDoSomething(); 
    } 

}; 

}

Así que ¿por qué creo que el uso del controlador en la vista no es bueno:

Estamos mezclando el controlador y ver implementaciones, haciendo nuevas dependencias.

También creo que View debería contener solo VIEWS y operaciones con ellos (y usar el controlador y algunos de sus métodos ya lucen como lógicos).

En el primer ejemplo, la vista le dice al controlador qué hacer. ¿Estas de acuerdo? ¡Parece que la vista controla el controlador!

En el segundo ejemplo, el controlador controla qué hacer y sólo dice a la vista qué hacer si algún botón (sólo vista sabe qué botón será) hace clic

siempre he usado el segundo esquema, pero después de leer un nuevo libro sobre mvc, que dice que tenemos que pasar el controlador a la vista, soy un poco confuso.

¿Puede ayudarme a comprender por qué me equivoco y mostrarme algunos ejemplos?

+0

Creo que el controlador y la vista no interactúan directamente. Ellos interactúan aunque modelo. para que el modelo conozca tanto el controlador como la vista, pero la vista y el controlador no se conocen entre sí. – gigadot

+2

habiendo dicho eso. MVC viene en muchas variantes y las implementaciones reales son diferentes en la práctica. – gigadot

+0

tiene usted razón ..., y ¿cómo cree que en este ejemplo, qué implementación es mejor? – pleerock

Respuesta

11

No hay un estándar MVC, ya que hay muchas implementaciones. Aquí hay una interpretación de MVC que se enseña en muchos libros de texto:

La definición del controlador en esta interpretación es que maneja eventos de la vista, por lo que la vista debe usar el controlador.

En MVC estándar, el modelo contiene y expone datos, el controlador manipula el modelo y acepta eventos de la vista, y la vista presenta el modelo y genera eventos para el controlador.

MVC se considera un sistema transaccional, donde una transacción se inicia por un evento. Las transacciones suelen tener este aspecto:

  1. Se genera un evento (como un clic de botón) en la vista.
  2. La información del evento se pasa de la vista al controlador.
  3. El controlador llama a los métodos del modelo para cambiarlo (los adaptadores y otros métodos de manipulación que pueden actualizar alguna base de datos).

Estos primeros pasos representan el enlace V-C y el enlace M-C. V-C existe porque los eventos se pasan de la vista al controlador para ser procesados ​​en lugar de la vista que los maneja directamente. El enlace M-C existe porque el controlador actualiza el modelo de acuerdo con el evento que se disparó.

Desde aquí, hay dos caminos. El primero:

  1. La transacción finaliza.
  2. Por separado, el modelo dispara sus propios eventos para indicar que ha cambiado.
  3. La vista está escuchando el modelo y recibe el evento, y actualiza su representación del modelo para reflejar los cambios.

Esta primera ruta representa una interpretación del enlace M-V. El enlace M-V es 1) la vista que obtiene información del modelo para sus datos, y 2) el modelo que indica a la vista que se actualice ya que se ha modificado.

La segunda ruta es solo un paso: una vez que el controlador ha procesado el evento, la vista se actualiza inmediatamente al actualizar todos sus elementos de IU. Esta interpretación del enlace M-V es que el modelo simplemente proporciona su información a la vista, al igual que el punto n. ° 1 del enlace M-V en la primera ruta anterior.

He aquí algunos de su código modificado para la arquitectura MVC que he descrito:

public class MyView implements View, ModelListener { 

    private Button myButton; 
    private Controller controller; 

    public MyView(Controller controller, Model model) { 
     myButton = new Button(); 
     myButton.setOnButtonClickListener(new ButtonClickListener() { 
      @Override 
      public void onClick() { 
       controller.onRegisterButtonClick(); 
      } 
     }); 
     this.controller = controller; 
     model.addModelListener(this); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    public void modelUpdated(Model model) { 
     // Update view from model 
    } 
} 

y el controlador:

public MyController implements Controller { 

    private Model model; 
    private View view; 

    public MyController(Model model) { 
     this.model = model; 
     this.view = new MyView(this, model); 
    } 

    private void manipulateModel() { 
     model.doSomeActions(); 
    } 

    public void onRegisterButtonClick() { 
     maniuplateModel(); 
    } 
} 

Entonces el modelo:

public class MyModel implements Model { 
    private List<ModelListener> modelListeners = new ArrayList<ModelListener>(); 

    public void addModelListener(ModelListener ml) { 
     if (!modelListeners.contains(ml)) { 
      modelListeners.add(ml); 
     } 
    } 

    public void removeModelListener(ModelListener ml) { 
     modelListeners.remove(ml); 
    } 

    public void doSomeActions() { 
     // Do something 
     fireUpdate(); 
    } 

    private void fireUpdate() { 
     // Iterates backwards with indices in case listeners want to remove themselves 
     for (int i = modelListeners.size() - 1; i >= 0; i-- { 
      modelListener.modelUpdated(this); 
     } 
    } 
} 

ModelListener es bastante simple:

public interface ModelListener { 
    void modelUpdated(Model model); 
} 

Esta es solo una interpretación. Si desea un mayor desacoplamiento entre las diferentes partes, debe consultar el Presentation, Abstraction, Control (PAC) pattern. Está más desacoplado que MVC, y también es ideal para sistemas distribuidos. Es excesivo para aplicaciones web, móviles y de escritorio simples, pero algunas aplicaciones cliente/servidor y la mayoría de las aplicaciones en la nube se pueden beneficiar de este enfoque.

En PAC, tiene tres partes, presentación, abstracción y control, pero la abstracción y presentación (el modelo y la vista) no interactúan entre sí.En cambio, la información pasa solo dentro y fuera del módulo de control. Además, puede tener múltiples submódulos PAC que interactúan entre sí solo a través de sus controles, prestándose a un buen patrón para sistemas distribuidos. Básicamente, el módulo de control es el centro principal de cualquier transferencia de datos.

Esencialmente, su interpretación de MVC puede ser diferente a la mía o la de ellos. Lo que importa es que elija un patrón arquitectónico y lo siga para mantener su código mantenible en el futuro. Y tienes razón en que hay formas de desacoplar MVC aún más. De hecho, su ejemplo es un poco como PAC, pero en lugar de eliminar el enlace V-C, elimina el enlace M-V.

En cualquier caso, siga una arquitectura, documento su arquitectura (para que la gente sepa cuál es su interpretación), y no se desvíe de eso.

+0

Gracias por su respuesta. Agradezco su consejo y aprendería más sobre el patrón PAC – pleerock

+0

¿Quién agregaría las 'vistas' en el' modelListeners' ArrayList en la clase 'MyModel'? ¿Eso se haría en 'MyController' donde en la clase' MyController' harías 'modelo. addModelListener (ver) '? – CapturedTree

+1

Claro, creo que el controlador sería el lugar apropiado en este ejemplo, sí. Entonces, en el constructor del controlador: 'model.addModelListener (view);' Opcionalmente, podría hacer que la interfaz 'View' amplíe' ModelListener' para que sepa que siempre será un oyente. O haga que la interfaz 'View' implemente un método que devuelva' ModelListener'. Hay muchas opciones. Como dije, elija una implementación y quédese con ella :) – Brian

Cuestiones relacionadas