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.