2010-02-24 13 views
8

Sto cercando un articolo o un'esercitazione che fornisca un esempio di come dovrebbe essere un modello MVC aggiornato (2.0?) Con il framework Swing.Esempio MVC Swing aggiornato + Domanda

Inoltre, essendo più abituato a un'architettura a più livelli, mi piacerebbe sapere come gli oggetti dominio o POJO si adattano all'immagine. Ho ragione nell'assumere che siano separati e chiamati dalla modella? Per quanto riguarda il modello stesso, ci sono convenzioni ampiamente utilizzate in termini di raggruppamento di classi in pacchetti?

TIA,

James P.

risposta

26

Questa è una grande domanda. Condividerò alcuni pensieri con te su questo argomento e vedrò cosa ne verrà fuori.

L'oscillazione è più Modello-> Vista che Modello-> Visualizza-> Controller. Il problema con Model-> View è che tipicamente le applicazioni Swing creano una sottoclasse di un oggetto View e che gli oggetti diventano sia View che Controller per quella vista in uno solo. Il lavoro straordinario in grandi applicazioni porta a molti problemi e codice spaghetti.

Quello che sto facendo da diversi anni è creare un oggetto separato chiamato Controller che non estenda alcuna classe UI. È un oggetto vecchio e semplice a questo riguardo. Questo Controller sarà incaricato di istanziare i componenti di livello superiore per la Vista, collegando gli ascoltatori alla vista per rispondere all'utente, e girandosi e facendo chiamate sul modello per eseguire il lavoro.

La vista sottoclasse Swing. La vista è responsabile della risposta agli eventi del mouse, eventi della tastiera, ecc. Qualsiasi tipo di evento specifico di Swing viene gestito nella vista. Fornirà inoltre metodi di alto livello per l'aggiornamento della vista che il controller utilizzerà per richiamare per aggiornare l'interfaccia utente. Anche i modelli di altalena classici sono separati dal View, perché la tua scelta di componenti è molto legata ai modelli che utilizzerai. La View si occupa anche di inviare eventi di alto livello al Controller e il Controller è incaricato di rispondere a quegli eventi di alto livello. Questi eventi potrebbero essere UserEvent.ADD, UserEvent.EDIT, AuthenticationEvent.LOG_IN, AuthenticationEvent.LOG_OUT, ecc. Questi eventi sono eventi dell'applicazione e sono più simili a ciò che può essere riconosciuto da un gestore di prodotto. Il controller non risponde a Mouse, ChangListener, ecc. In realtà ho costruito il mio EventDispatch ed Event framework perché questi sono così difficili da estendere e utilizzare in modo efficace. La vista funziona come:

public void mouseClicked(MouseEvent evt) { 
    User u = getUserAt(evt.getPoint()); 
    dispatch(new UserEvent(UserEvent.EDIT, u)); 
} 

Nel mio controller ho metodi semplici che sono collegati a quegli eventi. Qui potrebbe essere un esempio di uno:

@EventCallback(command = "exit") 
public void exit(AppEvent evt) { 
    onExit(); 
} 

@EventCallback(command = "help.about") 
public void showAbout(AppEvent evt) { 
    audioFinderFrame.showAboutDialog(engine.getLicenseInfo()); 
} 

@EventCallback(command = MediaSourceEvent.START_REFRESH) 
public void refreshStarted(final MediaSourceEvent event) { 
    if(frame != null) frame.refreshMediaSource(event.getSource(), true); 
} 

Le annotazioni sono un'estensione devo aggiungere metodi listener di eventi rapidamente ad una sorgente EventDisptach. Ma il punto è che ogni metodo sul controller viene richiamato dalla vista utilizzando eventi di alto livello. Ciò consente al controller di essere in qualche modo isolato da come viene visualizzata la vista. Il metodo di accesso del Controller non deve preoccuparsi di quali componenti compongono la vista. Ha appena ricevuto un evento ed esegue il lavoro. Il Controller è responsabile del flusso dell'applicazione.

Poiché il sistema di eventi è separato dallo Swing, lo riutilizza nei livelli del modello in modo che il modello possa inviare nuovamente gli eventi al Controller e il Controller può trasmettere tali modifiche all'interfaccia utente.

Il modello e il controller sono POJO. Capiscono gli eventi, ma è tutto. Il modello è la logica dell'applicazione che include un livello di DAO, servizi che potrebbero eseguire lavori in background, qualsiasi livello di servizio che comunica con il server e oggetti che la maggior parte delle persone potrebbe dire sono DTO.Non prescrivo l'idea che un DTO dovrebbe essere solo semplice struttura getter/setter. Riesco a permettere qualche logica, perché sono l'unica cosa che fluttua tra tutti gli strati. Poiché ogni livello ha accesso ad essi, forniscono un luogo ideale per centralizzare la logica che ogni livello può riutilizzare. La vista, il controller e il modello possono accedere a questi metodi, quindi perché non metterli nell'oggetto che si muove tra di loro.

In genere questa logica è più vicina alla logica aziendale o alla logica di manutenzione del modello. Sto attento ad accoppiare sistemi di architettura più grandi con questi metodi. Questi metodi non sono in grado di comunicare con il database, o richiamano i metodi lato server in modo che non possano riportare riferimenti a pezzi di architettura più grandi. Hanno tutti i vantaggi delle DTO: leggere, facilmente costruibili, basse dipendenze, ma mantengono ancora i principi del design orientato agli oggetti: incapsulamento, riutilizzo e occultamento delle informazioni.

Ho anche iniziato a utilizzare Spring per il cablaggio delle parti del modello con le loro dipendenze e dipendenze che il controller ha sul modello. Ho trovato che questo modello funziona molto bene ed è molto più piacevole che non usarlo. È anche bello avere accesso a tecnologie come i modelli Spring JDBC e modelli JMS se utilizzo queste tecnologie. Ma è facoltativo.

Non riuso mai i controller. I controller sono la cosa più specifica del tuo sistema, e le generalizzazioni ne rendono solo più difficile la manutenzione. Le generalità appartengono alla vista e al modello perché facilitano lo sviluppo. Quindi i modelli di design tendono a trovarsi su quei lati, ma raramente nel Controller. I controller sono semplici chiamate di metodo avanti e indietro.

Ho scoperto che fare questo ha reso la costruzione di UI Swing molto più semplice e più diretta. Ho meno probabilità di entrare in infiniti loop di eventi dall'ascoltare e manipolare due controlli contemporaneamente. Trovo anche che sia più facile testare e rompere il sistema a parte perché gran parte della mia logica esiste al di fuori della presa di Swing. Ciò rende possibili test funzionali senza un enorme toolkit che cerca di simulare clic del mouse, ecc.

Non c'è molto codice qui per illustrare scusa, ma spero che questo aiuti.

Problemi correlati