Utilizzo di MVP, come creare una vista da un'altra vista, collegata allo stesso oggetto modello

0

Sfondo

Utilizziamo il modello di progettazione Model-View-Presenter insieme al pattern factory astratto e il pattern "signal / slot" nella nostra applicazione, per soddisfare 2 requisiti principali

Miglioramento della testabilità (interfaccia grafica molto leggera, ogni azione può essere simulata nei test di unità) Rendi la "vista" totalmente indipendente dal resto, in modo da poter cambiare l'effettiva implementazione della vista, senza cambiare nulla Per fare ciò il nostro codice è diviso in 4 livelli:

Core: che contiene il modello Presentatore: che gestisce le interazioni tra le interfacce di visualizzazione (vedi sotto) e il nucleo Visualizza interfacce: definiscono i segnali e gli slot per una vista, ma non l'implementazione Visualizzazioni: l'effettiva implementazione delle viste Quando il relatore crea o si occupa di viste, utilizza una fabbrica astratta e conosce solo le interfacce di visualizzazione.

Fa il binding segnale / slot tra le interfacce delle viste. Non si preoccupa dell'attuazione effettiva. Nel livello "views", abbiamo uno stabilimento concreto che si occupa di implementazioni.

Il meccanismo segnale / slot è implementato utilizzando un framework personalizzato basato su boost :: function.

In realtà, quello che abbiamo è qualcosa del genere: link

Tutto funziona bene.

Il problema

Tuttavia, c'è un problema che non so come risolvere.

Prendiamo ad esempio un esempio di trascinamento della selezione molto semplice.

Ho due ContainersViews (ContainerView1, ContainerView2). ContainerView1 ha un ItemView1. Trascino ItemView1 da ContainerView1 a ContainerView2.

ContainerView2 deve creare un ItemView2, di un tipo diverso, ma che "punta" allo stesso oggetto modello di ItemView1.

Quindi ContainerView2 riceve un callback che chiama l'azione drop con ItemView1 come parametro. Chiama ContainerPresenterB passandogli ItemViewB

In questo caso ci occupiamo solo di visualizzazioni. In MVP-PV, le viste non dovrebbero sapere nulla sul relatore o sul modello, giusto?

Come posso creare ItemView2 da ItemView1, non sapendo quale oggetto del modello è ItemView1 che rappresenta?

Ho pensato di aggiungere un "itemId" ad ogni vista, questo id è l'id dell'oggetto principale rappresentato dalla vista.

Quindi in pseudo codice, ContainerPresenter2 farebbe qualcosa di simile a

itemView2 = abstractWidgetFactory.createItemView2 (); this.add (itemView2, itemView1.getCoreObjectId ()) Non capisco troppo nei dettagli. Questo funziona. Il problema che ho qui è che quegli itemIds sono proprio come dei puntatori. E i puntatori possono essere penzoloni. Immagina che per errore, cancello itemView1, e questo elimina coreObject1. L'itemView2 avrà un coreObjectId che rappresenta un coreObject non valido.

Non esiste una soluzione più elegante e "a prova di proiettile"?

Anche se non ho mai fatto la programmazione ObjectiveC o macOSX, non ho potuto fare a meno di notare che il nostro framework è molto simile al framework Cocoa. Come affrontano questo tipo di problema? Non ho trovato informazioni più approfondite su questo su google. Se qualcuno potrebbe far luce su questo.

Spero che questa domanda non sia troppo confusa ...

    
posta Dinaiz 24.06.2011 - 10:24
fonte

1 risposta

1

Finalmente abbiamo trovato una soluzione: - Quando inizi a trascinare un oggetto, la vista invia un segnale di "trascinamento" al suo controllore. Il controller ottiene l'oggetto del modello e inserisce un puntatore su di esso in una "DragandDrop-board" condivisa (pensatela come un blocco appunti)

  • Quando si rilascia, la vista invia un segnale "drop" al suo controller. Il controller ottiene l'oggetto dalla scheda di trascinamento e rilascio e aggiorna il modello di conseguenza.

Se si utilizza un tipo di puntatore intelligente è abbastanza facile assicurarsi che il puntatore sia ancora valido dopo il rilascio.

    
risposta data 16.09.2011 - 06:10
fonte

Leggi altre domande sui tag