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 ...