Possiedo un client Java che desidera comunicare con un dispositivo tramite messaggi tramite comunicazione seriale. Il client dovrebbe essere in grado di utilizzare un'API pulita, estrapolando i brutti dettagli della comunicazione seriale. Il client può inviare molti tipi di messaggi attraverso quell'API e ottiene le risposte. Sto cercando un consiglio su quale modo è meglio implementare questa API.Come progettare un API di tipo safe message in Java?
Per semplicità, diciamo che abbiamo solo due tipi di messaggi: HelloMessage
che innesca un HelloResponse
e InitMessage
che innesca una InitResponse
(in realtà, ci sono molti di più)
Progettare l'API (vale a dire, l'astrazione Java il dispositivo) ho potuto avere:
Un metodo per tipo di messaggio:
public class DeviceAPI {
public HelloResponse sendHello(HelloMessage){...}
public InitResponse sendInit(InitMessage){...}
... and many more message types ....
Questo è ben sICURO tipo. (Potrebbe anche essere più volte lo stesso metodo send()
, sovraccarico, ma è quasi lo stesso). Ma è molto esplicito e non molto flessibile - non possiamo aggiungere messaggi senza modificare l'API.
mi potrebbe anche avere un unico metodo di invio, che prende tutti i tipi di messaggi:
class HelloMessage implements Message
class HelloResponse implements Response
...
public class DeviceAPI {
public Response send(Message msg){
if(msg instanceof HelloMessage){
// do the sending, get the response
return theHelloResponse
} else if(msg instanceof ...
Ciò semplifica l'API (solo metodo) e permette di tipi di messaggio aggiunta di ulteriori successiva senza cambiare l'API. Allo stesso tempo, richiede che il Cliente verifichi il tipo di risposta e lo trasmetta al tipo giusto.
Codice cliente:
DeviceAPI api = new DeviceAPI();
HelloMessage msg = new HelloMessage();
Response rsp = api.send(msg);
if(rsp instanceOf HelloResponse){
HelloResponse hrsp = (HelloResponse)rsp;
... do stuff ...
Questo è brutto a mio parere.
Che cosa mi consiglia? Ci sono altri approcci che danno risultati più puliti?
Riferimenti benvenuti! Come hanno fatto gli altri a risolvere questo?
Un tipo parametrizzato con enum potrebbe essere una possibilità? O questo non è possibile (affatto). – skiwi
Controlla il tipo di "Risposta" e lanci poi HelloMessage. Sembra grottesco. Ad ogni modo, è possibile nascondere le operazioni "instanceOf" e "casting" nelle classi di implementazione. – arjacsoh
Non penso che dover controllare i tipi sia brutto, è probabile che lo implementerei anche io. Se non vuoi questo, penso che il punto giusto da riconsiderare sia il tuo modello; cosa rende necessario che queste risposte siano oggetti diversi? Non possono essere generici, per esempio? –