2013-03-08 11 views
7

Sto provando ad applicare il pattern MVC nell'applicazione swing. Tuttavia mi trovo di fronte a due problemi principali dato che hai una gerarchia nidificata di panel, ad es. Parent -> Child -> Grand Child -> Grand Grand Child.Swing MVC - Propagazione di eventi e condivisione dati

Problema 1: come trasferire i dati tra controller e vista quando si dispone di una simile gerarchia? Se vado a trasmettere dati da genitore a figlio, ci saranno molte duplicazioni e se cambierò un bambino tutti i genitori avranno bisogno di un cambiamento. Non voglio che le viste accedano direttamente ai dati da db e voglio che i dati vengano trasferiti alle viste solo attraverso il controller.

Problema 2: come propagare gli eventi dalla vista al controller in una simile gerarchia? Sto pensando di usare PropertyChangeListener. La vista verrà eseguita come evento FirePropertyChange se qualsiasi azione deve essere intrapresa dal controller. Il controller ascolterà per questi eventi ed eseguirà alcune azioni. Ma ancora una volta se lo faccio per la gerarchia, allora ci sarà la duplicazione del codice.

Ho tre idee che potrebbero essere utili:

  1. di utilizzare controller per ciascun gruppo di esperti, ma questo in questo modo mi si concluderà con un sacco di controllori.
  2. Utilizzare il modello di progettazione Mediatore che fornirà la comunicazione tra le viste e il controller.
  3. Utilizzare un ricevitore centrale & Notificatore che ascolterà tutti gli eventi di modifica delle proprietà dalle viste e notificherà i controller interessati. ma questo risolverà solo il mio secondo numero:

Si prega di fare riferimento al diagramma seguente per avere una foto della 3 ° idea. Nel caso del 2 °, il Mediatore verrà al centro.

Si prega di valutare e fammi sapere se qualcuno ha implementato tale problema in un modo migliore.

enter image description here

+2

Marting Fowler ha pubblicato una serie di articoli sull'architettura di presentazione (non avere alcun collegamento a portata di mano, mi dispiace, ma dovrebbe venire vicino alla parte superiore di una ricerca :-) – kleopatra

+0

Alcuni link _model-view-presenter_ (MVP) sono citati [ qui] (http://stackoverflow.com/a/15181906/230513). – trashgod

risposta

1

Ho un suggerimento per il problema 1:

Si può avere un ViewModel che contiene una proprietà di un altro vista del modello. E sul metodo del controller, devi solo ricevere il ViewModel principale perché il raccoglitore modello associa tutte le proprietà per te.

public class GrandChildViewModel{ 
    public Int32 SelectedDropDownItem { get; set; } 
    public List<Foo> ListOfFoo { get; set; } 
} 

public class ChildViewModel{ 
    public String Name { get; set; } 
    public Int32 Age { get; set; } 
} 
public class FatherViewModel{ 
    public ChildViewModel Child { get; set; } 
    public GrandChildViewModel GrandChild { get; set; } 
} 

Questo è un esempio della gerarchia. La tua vista farà riferimento solo a FatherViewModel. E i tuoi controller riceveranno anche FatherViewModel. Il modelBinder sarà automatico fare il suo lavoro, se si crea il codice HTML come:

@Html.TextBoxFor(m => m.Child.Name) 

Si renderà l'ingresso:

<input type="text" id="Child_Name" name="Child_Name" /> 
+0

Scusa, ma non ho avuto la tua spiegazione. Potete indicarmi qualche riferimento o link per la stessa cosa? – Atul

+0

Questo link qui, ha una risposta con un viewModel che contiene un altro ViewModel: http://stackoverflow.com/questions/3267015/model-binding-for-a-model-contain-multiple-objects – TiagoBrenck

+0

L'idea è di rappresentare il tuo gerarchia in View Models e creane uno per essere il "padre" di tutti, contenente le proprietà di tutti gli altri ViewModels. Questo "padre" sarà responsabile di trasferire tutte le informazioni modificate o digitate nella vista. – TiagoBrenck

1

Problema 1: Come trasferire i dati tra il controller e view quando hai una tale gerarchia? Se passo e passo i dati da genitore a figlio, allora ci saranno molte duplicazioni e se cambio un figlio tutti i genitori richiederanno una modifica. Non voglio che le viste accedano direttamente ai dati di da db e voglio che i dati vengano trasferiti alle viste solo attraverso il controller .

Cosa ne pensi di ignorare la gerarchia e adottare un approccio più lineare registrando le visualizzazioni con un controller pertinente? I dati potrebbero essere ottenuti attraverso un modello da cui le modifiche sarebbero state attivate attraverso un modello Observer o Listener.

Con questo non si verificherà alcuna duplicazione. Tutto sarebbe centralizzato in un modello o in una serie di modelli. Il controller oi controller possono eseguire una notifica su un elenco di viste registrate dopo che si è verificata un'azione dell'utente o un evento esterno.

Inoltre, le visualizzazioni non devono assolutamente accedere alla fonte dati come dici tu. Qui dovrebbe esserci almeno uno strato di astrazione. Se il controller utilizza il modello di mediazione, ciò che farei è gestirlo inoltrando le richieste a un'interfaccia in un livello dati aggiuntivo.

Pensando ulteriormente, non penso che sarebbe una buona idea effettuare la registrazione attraverso la vista. Quindi terrei questo separato. Inizializza le visualizzazioni a mano o trova un modo per scorrere le visualizzazioni di cui hai bisogno. Forse ottieni le tue opinioni attraverso una specie di fabbrica che automatizza questo passaggio.

Problema 2: Come propagare gli eventi dal punto di vista al controllore in una gerarchia come ? Sto pensando di usare PropertyChangeListener. La vista sarà evento firePropertyChange se qualsiasi azione deve essere eseguita dal controller. Il controller ascolterà per questi eventi ed eseguirà un'azione. Ma di nuovo se lo faccio per la gerarchia allora ci sarà la duplicazione del codice.

Ancora, è possibile adottare un approccio lineare. Quando una vista è registrata, il Controller può aggiungere gli ascoltatori ad essa. Oppure si potrebbe fare in modo che la vista invii alcuni messaggi semantici di stile (ad es. DoAction ("Salva")) che possono essere gestiti tramite un meccanismo di invio. Vi lasceremo decidere come inoltrare i parametri.

Avrebbero bisogno di PropertyChangeListeners? Voglio dire, hai bisogno di quel tipo di granularità?

Ho tre idee che potrebbero essere utili:

di utilizzare controller per ciascun gruppo di esperti, ma questo in questo modo mi finirà con un sacco di controllori. Utilizzare il modello di progettazione Mediatore che fornirà la comunicazione tra le viste e il controller. Utilizzare un ricevitore centrale & Notifier che ascolterà tutte le modifiche di proprietà dell'evento dalle viste e notificherà i controller interessati. ma questo risolverà solo il mio secondo problema:

Questo suona vagamente come HMVC. Con questo approccio hai triadi di model-view-controller per ogni sottosistema. È un'idea interessante ma potrebbe essere disordinata e non è chiaro come si debba svolgere la gerarchia e come si ottiene il coordinamento/subordinazione.

Forse potresti avere una quarta classe neutra per ogni modulo/sottosistema della tua app in cui potresti collegare una vista, un modello e un controller con un'eccezione generata se uno di essi è mancante o errato.

Oppure, seguendo questa idea di un notificatore centrale, si potrebbe avere un controller centrale che agisce come un meccanismo di routing su altri controller specifici delle funzionalità o più azioni elementari.Il modo in cui un messaggio viene reindirizzato a questi dipende da te. Fai attenzione ai thread perché la centralizzazione renderà essenziale il design di questa classe.

Qualsiasi cosa tu faccia, cerca di rendere le cose il più semplici possibile. Dovresti essere in grado di avere una vista di prova con il modello e il controller senza troppi problemi.

+0

Grazie per i vostri commenti. Ho anche pensato di creare un controller per ogni vista (pannello) ma, come ho detto, in questo modo finirò con un sacco di controller. Al momento, una finestra di dialogo contiene un TabbedPane che ha circa due TabbedPane secondari e 6-8 JPanel. Se vado da questa parte, finirò con almeno 10 controller. E, in futuro, potrei dover aggiungere ulteriori visualizzazioni e controller per requisiti aggiuntivi. – Atul

+0

L'uso di un TabbedPane indica che i pannelli sono correlati, quindi come fare per avere un controller e/o un modello. Probabilmente dovresti comunque centralizzare in modo tale da controllare cosa succede nell'applicazione. Ad esempio, immagina se devi aggiungere un sistema di autorizzazione. Effettuare un cambio a livello di sistema su più classi sarebbe noioso. Quindi sembra una buona soluzione. –

+1

Penso, lo terrò così fin da ora. Vediamo come va. Grazie per i vostri suggerimenti. Bounty è tuo per l'aiuto :) – Atul

1

Stavo affrontando un problema simile quando ho finito per utilizzare this HMVC Pattern. Sì, hai ragione, nel senso che ci sarà un sacco di controller. Ma è anche vero che ti fornirà una chiara separazione delle preoccupazioni nel codice. È possibile limitare il numero di controller creando alcuni widget compositi di alto livello specifici dell'applicazione. In questo caso, la gerarchia può essere limitata al massimo a 2 o 3 livelli e i controllori possono essere concatenati per delegare eventi a qualsiasi genitore/figlio.

Una volta caricati i dati dal server, è anche possibile mantenere la mappa di sessione per avere un po 'di sollievo per avere un rapido e easy access to frequently required data - tuttavia non lo favorisco molto.

Il modello funziona abbastanza bene se il team di sviluppo lo comprende e lo segue correttamente.

Problemi correlati