Architettura per lavorare con diversi dispositivi

1

Creo un'applicazione per un sistema, che consiste di diversi dispositivi, ognuno dei quali dovrebbe essere controllato da un computer tramite una delle interfacce hardware standard e potrebbe essere accessibile via Ethernet (Sockets), Virtual COM Port, pronto per -usare l'API C ++ di terze parti, ecc.).

La mia applicazione dovrebbe avere la GUI per gestire tutti i dispositivi, e alcuni dati dai dispositivi devono essere aggiornati frequentemente.

Normalmente ogni dispositivo ha il proprio protocollo di gestione specifico, che è presente come elenco di formati di comando, ad esempio: Intestazione (4 byte specifici), codice comando (2 byte), dimensione dati, dati, crc, ....

Caratteristiche:

  • Ogni dispositivo dovrebbe essere controllato dai comandi
  • Lo stato di integrità di ogni dispositivo dovrebbe essere ricevuto periodicamente e visualizzato sulla GUI
  • Generalmente la comunicazione con un dispositivo consiste nel trasmettere un comando e ricevere una risposta.

I problemi:

  • Nessun dispositivo risponde istantaneamente (sono necessari thread o async)
  • Se il dispositivo smette di funzionare o perde la connessione, è necessario attendere un po 'di timeout
  • "Business logic" dovrebbe avere un facile accesso a tutti i dispositivi contemporaneamente

Domande: quali soluzioni famose e buone (scheletri di interfaccia, articoli) sono già presenti per un problema del genere? Non voglio usare una classe "Dio" e inserirvi dozzine di membri.

    
posta Vladimir Bershov 21.03.2018 - 09:12
fonte

1 risposta

3

Interfacce

Bene, chiaramente l'uso delle interfacce è fondamentale qui. Pensa a un determinato dispositivo, ai tipi di richieste che potresti farne, quindi crea un'interfaccia attorno ad esso. Dovresti utilizzare una factory per creare un'istanza di ogni istanza di questa interfaccia, ma altrimenti il tuo programma non dovrebbe preoccuparsi della natura del dispositivo o dell'implementazione utilizzata.

interface Device {
    Future<Status> getHealthStatus();
    int            getTimeout();
}

Se c'è un aspetto specifico di un dispositivo, come il timeout dovrebbe essere più lungo attraverso uno smartphone, quindi avere una proprietà di timeout configurabile che è impostata di default su un valore più alto in fabbrica o nell'istanza stessa. Il programma che gestisce la richiesta deve quindi solo leggere il valore di timeout di un dispositivo per sapere per quanto tempo attendere una risposta di richiesta, eliminando quindi la necessità di gestire qualsiasi dispositivo in modo diverso.

Futures

Tieni presente che getHealthStatus() restituisce Future<Status> . Per il futuro, mi riferisco a un oggetto che rappresenta una risposta asincrona. L'istanza futura viene immediatamente restituita (sincrona), tuttavia consente di lavorare finché non è necessario conoscere la risposta effettiva. Tradizionalmente, ottieni un'istanza di Status chiamando Future.get() . Ciò interrompe il thread corrente fino a quando viene risolta l'istanza Status . Questo ti dà la flessibilità di gestire la chiamata in modo sincrono o asincrono come richiesto (nel primo caso chiameresti Future.get() immediatamente dopo la chiamata a getHealthStatus() ).

Questo concetto esiste in molte lingue. In javascript viene comunemente definito Promessa. Usare questo per organizzare le tue chiamate sincrone / asincrone è anche importante per il tuo programma senza dubbio.

Livello API

Fino a questo punto, abbiamo solo parlato della gestione interna delle richieste al tuo programma, ma è molto utile creare un livello API esplicito per gestire il lavoro di grugnito di basso livello delle richieste e delle risposte e tradurli in semplici chiamate ai tuoi corsi interni. La gestione ideale dei timeout verrebbe gestita qui. Preparati a gestire la possibilità di timeout e tentativi in questo livello. Il resto del tuo programma dovrebbe essere astratto da questo particolare aspetto. L'unico modo in cui il resto del programma viene reso consapevole dei problemi è un'istanza di stato di timeout corretta o forse un'eccezione generata, solo dopo che l'operazione è stata considerata irrecuperabile.

Conclusione

Strutturando il tuo programma in questo modo, hai una chiara interruzione delle responsabilità e della gestione dei dispositivi. Utilizzando le interfacce per dispositivi, il tuo programma non dovrebbe mai preoccuparsi di conoscere il tipo di dispositivo dall'altra parte eccetto durante la sua creazione. L'uso di Futures renderà le chiamate asincrone semplici e facilmente gestibili. Utilizzando un livello API, puoi semplificare efficacemente il programma concentrandoti sull'essenza della richiesta e della risposta e permettendoti di adattare facilmente il tuo programma per le modifiche future.

    
risposta data 21.03.2018 - 09:39
fonte

Leggi altre domande sui tag