2010-10-23 5 views
7

Sto imparando GWT e ho letto in più posti che utilizza l'architettura MVP calza meglio per sviluppare un'applicazione GWTGWT MVP architettura vantaggi

Ho anche letto che la sua facile da fare test utilizzando l'MVP ARCH.Can qualcuno mi spiega perché è facile fare test usando l'architettura MVP.

Inoltre sto lavorando a un progetto utilizzando MVP e trovo molto noioso rendere la vista connessa al database. Voglio dire che devo aggiornare il mio relatore, servizio, servizioAsync, servicImpl, Facciate per poter effettuare la connessione al database.

Quindi qualcuno può fornirmi l'essenza di MVP per GWT? Apprezzerei un paio di esempi.

risposta

23

separazione tra il presentatore (che contiene la logica) e vista (un involucro muto intorno controlli UI) consente di:

  • scrivere unit test per i presentatori funzionare senza dover dell'ambiente corrispondente (desktop, browser GWT) logica
  • riutilizzo front-end senza essere legati ad un particolare insieme di quadro widgets/UI

il caso d'uso quest'ultimo è raro, quindi concentriamoci sulla idoneità del modello MVP automatizzata, programmatica test. Con un team di sviluppatori questo spesso assume la forma di un ciclo di build/test continuo utilizzando Hudson (o simile) su un server headless, dove non è pratico aprire un browser Web, creare controlli, ecc. Ogni volta che viene eseguito un test.

L'utilizzo tipico di MVP + GWT è che le viste implementano un'interfaccia fornita dal presentatore e spesso questa interfaccia è definita in termini di altre interfacce generiche. Ecco un semplice presentatore che incrementa un'etichetta numerica quando un tasto è scattato - notare che, invece di esporre le TextBox e Button direttamente, la vista restituisce generici HasText e HasClickHandlers casi:

public class ButtonClickPresenter { 
    public interface View { 
     HasText currentValue(); 
     HasClickHandlers incrementButton(); 
    } 

    private final View myView; 
    private int currentValue = 0; 

    public ButtonClickPresenter(View myView) { 
     this.myView = myView; 
     this.myView.currentValue().setText("0"); 

     this.bind(); // for the sake of demonstration 
    } 

    public void bind() { 
     this.myView.incrementButton.addClickHandler(
      @Override 
      new ClickHandler() { 
       void onClick(ClickEvent event) { 
        currentValue ++; 
        myView.currentValue().setText(
         Integer.toString(currentValue)); 
       } 
      }); 
    } 
} 

La vista "reale" ritorna UI widgets (creati tramite UiBinder in questo esempio):

public class ButtonClickView implements ButtonClickPresenter.View { 
    // ... skipped UiBinder initialisation ... 

    @UiField Label currentValueLabel; 
    @UiField Button incrementButton; 

    @Override 
    public HasText currentValue() { 
     return currentValueLabel; 
    } 

    @Override 
    public HasClickHandlers incrementButton() { 
     return incrementButton; 
    } 

    // ... etc ... 
} 

che unit test creano un'implementazione fittizio (o utilizzare Mockito, EasyMock, etc.) e pertanto non richiedono alcun componente UI:

public class ButtonClickPresenterTest { 
    ButtonClickPresenter presenter; 
    ClickHandler currentHandler; 
    String currentText; 

    @Before 
    public void setUp() { 
     presenter = new ButtonClickPresenter(
      // dummy view - just stores label text in a String and 
      // keeps track of the Presenter's click handler 
      new ButtonClickPresenter.View() { 
       @Override 
       public HasText currentValue() { 
        return new HasText() { 
         @Override public String getText() { return currentText; } 
         @Override public void setText(String text) { currentText = text; } 
        }; 
       } 

       @Override 
       public HasClickHandlers incrementButton() { 
        return new HasClickHandlers() { 
         @Override 
         public HandlerRegistration addClickHandler(ClickHandler handler) { 
          currentHandler = handler; 
         } 
        }; 
       } 
      }); 
    } 

    @Test 
    public void testIncrement() { 
     // initial value 
     assertEquals("0", currentText); 

     // clicking the button should increment the number 
     currentHandler.onClick(null); 
     assertEquals("1", currentText); 
    } 
} 

Per quanto riguarda il prossimo paragrafo: le vostre viste non dovrebbero assolutamente connettersi al database! Il presentatore deve richiedere i dati tramite Service/ServiceAsync (o un'astrazione come gwt-dispatch o gwt-platform), quindi chiamare i metodi sulla vista per popolare l'interfaccia utente.

Tra l'altro, questi ultimi due link (insieme con gwt-presenter) sono un buon inizio, se siete alla ricerca di esempi di codice GWT MVP - combinato con Google GIN forniscono strutture per legare tutte queste cose insieme.

Detto questo, sono d'accordo - la combinazione di GWT + MVP + Java può essere duro lavoro e estremamente verbose (Sono contento di non dover lavorare con esso molto in questi giorni). L'alternativa, tuttavia, è ancora meno attraente: una palla di spaghetti non controllabile e non gestibile ...

+0

Fantastico !! Grazie – Barry