Qual è una buona strategia per legare oggetti vista a modelli di oggetti in C ++?

5

Immagina di avere un modello di dati ricco rappresentato da una gerarchia di oggetti.

Ho anche una gerarchia delle viste con viste che possono estrarre i dati richiesti dagli oggetti del modello e visualizzare i dati (e consentire all'utente di manipolare i dati).

In realtà, potrebbero esserci più gerarchie di viste che possono rappresentare e manipolare il modello (ad esempio una vista panoramica-dettagli e una vista manipolazione diretta).

Il mio attuale approccio per questo è che il livello controller memorizzi un riferimento all'oggetto modello sottostante nell'oggetto View. L'oggetto vista può quindi ottenere i dati correnti dal modello per la visualizzazione e può inviare i messaggi dell'oggetto modello per aggiornare i dati. Gli oggetti di vista sono effettivamente osservatori degli oggetti del modello e gli oggetti del modello trasmettono notifiche quando cambiano le proprietà.

Questo approccio consente a tutte le viste di aggiornarsi simultaneamente quando una vista cambia il modello.

Implementato con attenzione, tutto funziona. Tuttavia, richiede molto lavoro per garantire che nessuna vista o oggetti modello mantengano riferimenti stantii agli oggetti del modello. L'utente può eliminare oggetti modello o sotto-gerarchie del modello in qualsiasi momento. Garantire che tutti gli oggetti vista che contengono riferimenti agli oggetti del modello che sono stati cancellati richiede tempo e difficoltà.

Sembra che l'approccio che ho intrapreso non sia particolarmente pulito; anche se non voglio avere codice esplicito nel livello controller per mediare la comunicazione tra le viste e il modello, sembra che ci debba essere un approccio migliore (implicito) per stabilire i collegamenti tra la vista e il modello e tra oggetti modello correlati.

In particolare, sto cercando un approccio (in C ++) che comprenda due punti chiave:

  1. Esiste una relazione molti a uno tra la vista e gli oggetti del modello
  2. Se l'oggetto modello sottostante viene distrutto, tutti gli oggetti di visualizzazione dipendenti devono essere ripuliti in modo che non esistano riferimenti stantii

Mentre shared_ptr e weak_ptr possono essere usati per gestire le durate degli oggetti del modello sottostante e consente riferimenti deboli dalla vista al modello, non forniscono la notifica della distruzione dell'oggetto sottostante (lo fanno nel percepire che l'uso di un weak_ptr obsoleto consente la notifica), ma ho bisogno di un approccio che notifica agli oggetti dipendenti che il loro riferimento debole sta andando via.

Qualcuno può suggerire una buona strategia per gestirlo?

    
posta B.J. 26.07.2013 - 05:05
fonte

3 risposte

3

Tieni presente che stai descrivendo accuratamente il osservatore modello di progettazione, dato che l'oggetto del modello di dominio è l'oggetto e i punti di vista per essere osservatori. Si noti inoltre che il modello di osservatore implica un livello di astrazione più elevato rispetto a un puntatore intelligente e che non esiste una corrispondenza concettuale diretta tra i due.

Per implementare questo modello, è necessario innanzitutto assicurarsi che tutte le viste coinvolte (osservatori) implementino un'interfaccia comune, ad esempio ereditando una base comune, una classe astratta. Quindi, l'oggetto dominio (oggetto) può procedere con la gestione di una serie di riferimenti a istanze di detta interfaccia di osservazione e, se necessario, notificandoli tutti, chiamando i metodi di interfaccia appropriati.

I puntatori intelligenti possono essere utilizzati in questo schema per implementare i riferimenti gestiti dal soggetto.

    
risposta data 27.09.2013 - 12:31
fonte
0

Bene, puoi sempre creare il tuo puntatore intelligente che notificherà i referrer. Non è così difficile.

I puntatori deboli non hanno notifica perché richiederebbe una lista di riferimenti deboli esistenti e ciò richiederebbe a sua volta una sincronizzazione non banale in ambiente multi-thread mentre l'implementazione senza di essa richiede solo un ulteriore livello di riferimento indiretto. Ma soprattutto se si dispone di alcuni vincoli da cui i thread possono essere eliminati (i framework GUI sono in genere a thread singolo comunque), è possibile.

    
risposta data 26.07.2013 - 11:07
fonte
0

Se comprendo correttamente il tuo progetto, hai un modello di visualizzazione del modello.

Per migliorarlo, puoi utilizzare MVC progettare con l'osservatore modello, dove:

  • i controllori stanno solo connettendo modelli- > viste e viste-> i segnali dei modelli agli slot
  • Le viste
  • mostrano ciò che devono mostrare, ascoltano gli eventi rilevanti dal modello per aggiornare la vista e inoltrano l'interazione dell'utente ai modelli
  • I modelli
  • stanno implementando la logica. Gestiscono l'interazione dell'utente e invia eventi alle viste per informarli delle modifiche

In questo modo, se desideri distruggere un modello, puoi farlo senza troppe difficoltà. Dovrai anche interrompere le connessioni nel controller.

Qui puoi vedere come ho implementato MVC in qt5. Potrebbe evolversi in qualcosa di utile nel lontano futuro, ma per ora è solo a scopo dimostrativo:)

    
risposta data 04.12.2013 - 09:24
fonte

Leggi altre domande sui tag