Libreria di classi - Come comunicare tra oggetti che non sono a conoscenza l'uno dell'altro?

3

Sto cercando di migliorare le mie capacità e conoscenze di programmazione e ho letto alcuni dei modelli di design e dei video di YouTube, ecc. Un argomento che ho ritenuto interessante era che Singletons era un Anti-pattern che mi ha portato a un problema che non sono abbastanza sicuro di come risolvere. Permettimi di spiegare. Diciamo che ho creato una libreria di classi GPS. Nella libreria ho una classe chiamata GpsSensorUtil . Questa classe fa tutto ciò che ha a che fare con l'elaborazione di dati GPS come l'elaborazione di velocità, distanza, ecc. E genera eventi con queste informazioni. Quindi ora sto pensando hey, forse voglio vedere le informazioni GPS visivamente. Così creo un UserControl nella libreria che ascolterà gli eventi di GpsSensorUtil .

Il problema a cui sto pensando è come posso collegare GpsSensorUtil a UserControl in modo che UserControl possa ascoltare gli eventi da GpsSensorUtil ? In un'applicazione normale guarderei in DependancyInjection magari con Unity , ma poi dovrei trovare un modo per inizializzare e configurare il UnityContainer in quanto non esiste un punto di ingresso in una libreria di classi. Ho pensato di creare come un singleton un riferimento statico per il contenitore ma, come ho letto, non è una buona cosa.

Nella mia testa occorre considerare quanto segue.

  1. GpsSensorUtil non sa di UserControl e non ne ha bisogno.
  2. UserControler non ha bisogno di conoscere GpsSensorUtil , solo gli eventi che genera.
  3. Chiunque potrebbe utilizzare questa libreria, quindi non voglio limitarmi a un solo IoC come unità.

Qual è il modo migliore per avvicinarsi a qualcosa del genere?

    
posta Gaz83 13.06.2016 - 18:41
fonte

4 risposte

4

Se stai facendo un'interfaccia per i dati GPS, invariabilmente avrà una dipendenza dai dati GPS di qualche tipo. Avere quell'accoppiamento non è male, anzi. Se il controllo dell'utente dipende da un'interfaccia esplicita, stai permettendo al compilatore di dirti quando è mancante e stai dicendo ai tuoi utenti che cosa deve funzionare.

Tuttavia, rendendola un'interfaccia, stai effettivamente disaccoppiando il tuo controllo dall'implementazione del fornitore di dati GPS che le consente di cambiare liberamente. Il modo in cui la dipendenza viene fornita dipende dall'utilizzatore, che potrebbe persino utilizzare la propria fonte di dati, se lo desidera. Non c'è bisogno di contenitori IoC maledetti se non sono garantiti.

    
risposta data 13.06.2016 - 19:43
fonte
4

Poiché il UserControl è già stato disaccoppiato da GpsSensorUtil dagli eventi, non c'è bisogno di un'integrazione delle dipendenze da parte delle interfacce, il che complicherebbe solo le cose senza alcun beneficio aggiuntivo. Tuttavia, se ci sono molti eventi che devono essere collegati in un modo specifico tra questi due componenti, è un buon approccio non lasciare che questo gestisca ogni utente della tua libreria da solo, ma fornisca una funzione nella tua lib che questo per lui. E poiché non vuoi permetterti di conoscere UserControl di GpsSensorUtil , o viceversa, l'unico posto significativo è una classe aggiuntiva.

Quindi nella tua lib, fornisci una classe come UserControlBuilder o UserControlFactory che prende un oggetto GpsSensorUtil , crea un oggetto UserControl e fa il cablaggio degli eventi. Gli utenti della tua lib possono quindi utilizzarlo, quindi non hanno bisogno di scrivere il codice di cablaggio da soli (ma saranno ancora in grado di utilizzare GpsSensorUtil e UserControl completamente indipendenti l'uno dall'altro).

Non c'è bisogno di rendere UserControlBuilder un singleton, solo il fatto che un utente della tua libreria di solito avrà solo bisogno di un solo oggetto di quella classe non significa che la tua lib deve far rispettare che non ci saranno più oggetti di quella classe.

Se si desidera separare la costruzione di UserControl dal cablaggio degli eventi, ad esempio, per rendere più semplice l'uso di UserControl nella finestra di progettazione grafica dell'interfaccia utente, è comunque necessaria una classe aggiuntiva per il codice di cablaggio. In questo caso, chiama semplicemente la classe UserControlInitializer o qualcosa di simile e passa il UserControl e GpsSensorUtil precedentemente costruiti nella funzione di cablaggio fornita di quella classe.

    
risposta data 13.06.2016 - 19:59
fonte
1

Mantengalo semplice. GpsSensorUtil dovrebbe avere una proprietà evento e ControlUtil dovrebbe avere un gestore eventi pubblico. Quindi, nel codice principale che crea i due, dovresti avere una riga come gpsSensorUtilInstance.GPSEvent += controlUtilInstance.OnGPSEvent; . Nessun framework, nessun contenitore, nessuna dipendenza diretta tra le due classi.

    
risposta data 14.06.2016 - 01:26
fonte
0

Il modo di comunicare tra classi che non hanno conoscenza reciproca è tramite il passaggio di messaggi. Di solito c'è un bus o qualche altra forma di meccanismo di routing master che ogni classe registra con. Da quel momento in poi, ogni classe invia messaggi al bus senza alcun riguardo se un'altra classe li sta leggendo.

Quindi qui, la tua lib sta sparando eventi e la tua interfaccia utente li sta leggendo. Non è necessario conoscere nient'altro che il tipo di messaggi di eventi che riceveranno. Non c'è bisogno di interfacce o di collegamenti espliciti tra di loro, devono solo sapere come leggere e scrivere messaggi sul bus.

Funziona bene anche per sistemi distribuiti, quindi la tua lib GPS potrebbe inviare dati a un terminale remoto, se il tuo bus gestiva la trasmissione dei messaggi attraverso una rete anziché localmente.

    
risposta data 14.06.2016 - 12:26
fonte

Leggi altre domande sui tag