Che cos'è "Split Data Model", menzionato nel libro "Java Concurrency In Practice"?

4

Sto imparando la programmazione multithreading Java dal libro " Concorrenza Java in pratica ". Nel capitolo 9.4.2 Split Data Model , ho letto questo:

From the perspective of the GUI, the Swing table model classes like TableModel and treeModel are the official repository for data to be displayed. However, these model objects are often themselves "views" of other objects managed by the application. A program that has both a presentation‐domain and an application domain data model is said to have a split‐model design (Fowler, 2005).

In a split‐model design, the presentation model is confined to the event thread and the other model, the shared model, is thread‐safe and may be accessed by both the event thread and application threads. The presentation model registers listeners with the shared model so it can be notified of updates. The presentation model can then be updated from the shared model by embedding a snapshot of the relevant state in the update message or by having the presentation model retrieve the data directly from the shared model when it receives an update event.

The snapshot approach is simple, but has limitations. It works well when the data model is small, updates are not too frequent, and the structure of the two models is similar. If the data model is large or updates are very frequent, or if one or both sides of the split contain information that is not visible to the other side, it can be more efficient to send incremental updates instead of entire snapshots. This approach has the effect of serializing updates on the shared model and recreating them in the event thread against the presentation model. Another advantage of incremental updates is that finer‐grained information about what changed can improve the perceived quality of the display if only one vehicle moves, we don't have to repaint the entire display, just the affected regions.

Qual è il significato di "Split Data Model"? Puoi mostrarmi un esempio per aiutarmi a capirlo?

    
posta FireSun 14.01.2016 - 13:25
fonte

3 risposte

1

Il modello di dati del dominio di presentazione riguarda il rendering sullo schermo del modello di dati del dominio dell'applicazione. Ad esempio, supponiamo di avere una tabella nel modello di dati dell'applicazione e di voler presentare i dati, filtrati e / o ordinati come l'utente sceglie. In tal caso, la scelta del filtro e / o dell'ordinamento è un aspetto del dominio di presentazione. (Il filtro / ordinamento può essere rappresentato come dati e mantenuto, anche, se l'utente desidera recuperare la stessa vista.)

Separando le preoccupazioni del modello di presentazione dal modello applicativo, è facile per noi creare un'applicazione che può avere più viste simultanee (presentazioni) degli stessi dati dell'applicazione. Immagina un utente con più finestre aperte che guardano gli stessi dati dell'applicazione, anche se probabilmente presentati in modo leggermente diverso (nel nostro esempio, forse ordinati o filtrati in modo diverso).

Ora, immagina anche due o più utenti che guardano gli stessi dati (possibilmente con filtri / ordinamenti diversi). Una volta che più utenti hanno potenzialmente modificato gli stessi dati (tramite le loro presentazioni individuali), è necessario applicare il coordinamento a più thread (transazioni, blocchi o altro) sul modello dell'applicazione.

Al contrario, il modello di presentazione non avrà bisogno di coordinazione del threading (a meno che non si mantengano le visualizzazioni e si consentano a più utenti di modificarle).

    
risposta data 14.01.2016 - 17:11
fonte
0

L'idea qui è di incrementalmente cambiare le cose usando gli eventi invece di aggiornare il modello ogni volta che l'utente ha bisogno degli "ultimi dati".

Supponiamo ad esempio un'applicazione che mostri il contenuto di una tabella di database, ad esempio, in una casella di selezione. Di solito, quando aggiorni il componente, l'app interroga l'intera tabella del database e aggiorna l'intero elenco, anche se il 90% dell'elenco ha gli stessi elementi.

Supponiamo ora una seconda situazione. Hai una tabella di allarmi per diversi componenti. Invece di interrogarli periodicamente, attendi ognuno di loro per avvisarti quando succede qualcosa. Quindi in realtà stai ascoltando gli eventi invece di chiedere loro ogni volta "ok ok? Ok?"

Un esempio è OSGI . Ad esempio, Eclipse utilizza OSGI ( Equinox ) per gestire i suoi moduli e plug-in (infatti, Eclipse stessa è un grande plug-in manager). Quando si aggiorna un modulo o si installa un nuovo plug-in, non è necessario riavviare l'intera applicazione per caricare le modifiche. Invece, Eclipse viene notificato dal motore OSGI e ricarica solo quella parte che è stata aggiornata, tramite un evento. Quindi le modifiche vengono aggiornate in modo incrementale e, nella maggior parte dei casi, senza la necessità di riavviare l'app.

    
risposta data 14.01.2016 - 13:48
fonte
0

Considera software che controlla uno strumento complesso. Periodicamente esegue il polling dello strumento per leggere un gruppo di valori: tensioni, pressioni, percentuale di completamento, contrassegni di avviso, ecc. Immagina che i dati scendano come XML / JSON, o forse qualche forma binaria, tramite USB o Ethernet. Questi dati vengono visualizzati in una finestra di dialogo non modale che l'utente può monitorare. Quella finestra di dialogo potrebbe essere un'interazione a due vie, cioè ha un pulsante "Abort". In Java, probabilmente si dispone di un thread che esegue questo polling, quindi analizza i dati. Molte altre lingue farebbero simili.

Quindi, dove inserire i dati e come?

Da qualche parte nel profondo della finestra di dialogo c'è un pannello all'interno di un pannello che contiene uno slider o un pulsante o un campo di testo per mostrare questi risultati. È del tutto ragionevole che questo dato profondamente sepolto sia il modello THE , il vero e ufficiale archivio del vero stato ufficiale dello strumento? Ad esempio, se la tensione diventa troppo alta e si vuole far apparire un avviso o inviare una e-mail, questo codice deve guardare attraverso gli JPanel nidificati? No.

È ragionevole che il tuo Polling Thread sappia anche come trovare i pulsanti all'interno di quella finestra di dialogo? Dovrebbe saperlo fare (molto mano che saluta il codice errato) getComponent(EAST).getComponent(3).getStatusTextField().setText("4.56 pounds"); Quasi certamente no. Se stai seguendo Law of Demeter, potrebbe diventare un po 'più semplice, getEscapeModuleForCapsule3StatusTextField() . Ma anche questo crea un sacco di link tra il thread e la GUI. Che cosa succede se vuoi avere anche Android e una versione HTML5 del tuo codice? Cosa succede se il marketing cambia alcuni dei widget in Sliders o Spinners? Che ne dici di una versione europea che usa chilogrammi? Cosa succede se quel campo di tensione è in realtà 3 campi simili su tre diversi JPanel, due sono Text e uno a Spinner?

O.K., ammetto che sto esagerando un po 'i precedenti due problemi.

Soprattutto, che è il motivo principale per cui questo argomento è apparso su JCiP, anche se si lavora su tutti questi problemi e si progettano problemi in modo che il thread di polling possa arrivare ai widget rilevanti, è un dolore nel sedere per modificare il valore, perché Swing è single threaded . Tutte le chiamate provenienti dal thread di polling sono nella discussione sbagliata e devono essere racchiuse in awkward SwingUtilities.invokeLater(new Runnable() { public void run() {// real code here } });

Modello di dati condivisi

In un "Modello di dati condivisi", sei libero di fare le cose in modo discutibilmente molto più naturale. Definisci una classe InstrumentModel, una che abbia senso per la tua azienda e lo strumento, con setter, getter e, oh yeah, limiti assegni rilevanti. Potrebbe causare eventi speciali quando la tensione diventa troppo alta. Questo modello avrà molto più senso per i vostri scienziati e ingegneri interni rispetto a molti livelli di JPanel annidati. Questo modello deve essere fatto per essere sicuro.

Si noti che questo modello ha nessuna conoscenza se Swing, GWT, HTML5 o American Sign Language saranno l'output. È Disaccoppiamento . Il Polling Thread inserisce i dati in InstruementModel. Quindi (o qualcosa) attiva un evento nella GUI - nella forma più semplice, theHugeDialog.repaint(); Nota che in Swing queste richieste di ripetizione sono accodate, quindi, si spera, la tua finestra di dialogo non ridisegni 100s di volte per ogni modifica.

La GUI, in paintComponent() o simile (ci sono alcuni trucchi), quindi estrae i dati da InstrumentModel. È automaticamente in esecuzione sul thread Swing AWT appropriato , quindi non c'è bisogno di invokeLaters (). Dal momento che hai abilmente reso sicuro il thread InstrumentModel, la lettura dei dati non è in conflitto con i dati di scrittura di PollingThread. Se è presente anche un campo di testo VeryImportantVoltage nella finestra principale dell'applicazione, può essere aggiornato anche da InstrumentModel.

Questo è l'aggiornamento "snapshot" - in pratica, si ridisegna l'intera GUI. Se la GUI è enorme e si stanno aggiornando centinaia di volte al secondo, questo potrebbe essere troppo lento. Quindi si passa a un aggiornamento incrementale in cui vengono aggiornati solo i dati modificati. Questo diventa molto complicato molto rapidamente.

    
risposta data 15.01.2016 - 01:05
fonte

Leggi altre domande sui tag