Design / tecnologie appropriati per gestire la formattazione dinamica delle stringhe?

0

recentemente mi è stato affidato il compito di implementare un modo per aggiungere il supporto per il controllo delle versioni delle specifiche dei pacchetti hardware in una delle nostre librerie. Prima un po 'di informazioni sul progetto.

Abbiamo una libreria hardware che ha classi per ciascuno dei vari comandi che supportiamo l'invio al nostro hardware. Questi moduli hardware sono essenzialmente solo luci con pochi pulsanti e un display a 2 o 4 cifre. I pacchetti seguono generalmente il formato {SOH}AADD{ETX} , dove AA è il nostro codice di azione sentinella e DD è l'ID dispositivo. Queste specifiche del pacchetto sono diverse da un comando al successivo, ovviamente, e le diverse versioni del firmware supportano diverse specifiche. Ad esempio, nella versione 1 un codice azione di 14 potrebbe avere una specifica di {SOH}AADDTEXT{ETX} che sarebbe AA = 14 letterale, DD = ID dispositivo, TEXT = testo letterale da visualizzare sul dispositivo. Quindi usciamo con una revisione aggiungendo un byte esteso alla fine del pacchetto come questo {SOH}AADDTEXTE{ETX} . Supponiamo che il campo TESTO sia a larghezza fissa per questo esempio. Ora abbiamo aggiunto un nuovo campo all'estremità che potrebbe essere usato per specificare il colore o la velocità del flash del testo / dei pulsanti. Attualmente questa libreria java supporta solo una versione dei comandi, l'ultima.

Nella nostra libreria hardware avremmo una classe per questo comando, diciamo un DisplayTextArgs.java. Quella classe avrebbe i campi per l'ID del dispositivo, il testo e il byte esteso. La classe command esporrà un metodo che genera la stringa ( "{SOH}AADDTEXTE{ETX}" ) usando il valore della classe. In pratica creeremo la classe Args come necessario, popoliamo i campi, chiamiamo il metodo per ottenere la nostra stringa di pacchetti, quindi li spediamo attraverso il CAN.

Alcune delle altre specifiche dei nostri comandi possono variare per lo stesso comando, sulla stessa versione, a seconda di alcuni stati di runtime. Ad esempio, un altro comando per la versione 1 potrebbe essere {SOH}AA{ETX} , in cui questo codice di azione cancella tutti i moduli dietro uno specifico dispositivo di controllo del loro testo. Potremmo sovraccaricare questo pacchetto per avere campi opzione con più significati come {SOH}AAOC{ETX} dove OC è testo letterale, che dice al controller di cancellare solo il testo su un tipo specifico di modulo, e di lasciare gli altri da soli, o la specifica potrebbe anche avere un formato di opzione di {SOH}AADD{ETX} per cancellare il testo da un dispositivo specifico. Attualmente, nel metodo che genera la stringa del pacchetto, valuteremmo i campi della classe args per determinare quale specifica useremo durante la formattazione del pacchetto. Per questo esempio, sarebbe sulla falsariga di:

if m_DeviceID != null then use {SOH}AADD{ETX}
else if m_ClearOCs == true then use {SOH}AAOC{EXT}
else  use {SOH}AA{ETX}

Avevo preso in considerazione l'utilizzo di XML o un database per memorizzare stringhe di formato String.format, che erano collegate ai numeri di versione del firmware in alcune tabelle. Li caricheremo all'avvio e passeremo il numero di versione del firmware dei firmware attualmente in uso (posso interrogare i dispositivi per la loro versione del firmware, ma la versione non è inclusa in tutti i pacchetti come parte della specifica). Questo si rompe abbastanza rapidamente a causa della natura dinamica di come selezioniamo quale versione del comando usare.

Ho quindi considerato l'utilizzo di un motore di regole per creare possibilmente espressioni che potevano essere interpretate a runtume, per valutare lo stato della classe args e da quello selezionare la stringa di formato appropriata da utilizzare, ma il mio breve sguardo ai motori di regole per java spaventato me via con la sua complessità. Mentre sembra che potrebbe essere una soluzione praticabile, sembra eccessivamente complessa.

Quindi è per questo che sono qui. Non direi che il design è la mia abilità più strong, e sto avendo problemi a trovare il modo migliore per affrontare questo problema. Probabilmente non sarei in grado di cambiare radicalmente le lezioni di args, ma se il trade off fosse abbastanza buono, potrei essere in grado di convincere il mio capo che il cambiamento è appropriato.

Quello che vorrei dalla community è un feedback su alcune best practice / metodologie di progettazione / API o altre risorse che potrei usare per realizzare:

Logica per determinare quale gruppo di comandi utilizzare per una determinata versione del firmware Di questi comandi, quale versione di ciascun comando usare (in base allo stato delle classi args)
Mantenere la logica delle regole disaccoppiata dall'applicazione in modo da evitare la necessità di rilasci per ogni versione del firmware
Essere abbastanza semplice, quindi non ho bisogno di settimane di studio e di prove ed errori per attuare in modo efficace.

    
posta Mark W 05.06.2014 - 18:43
fonte

1 risposta

0

La specifica JavaComm astrae il supporto del driver attraverso l'uso di advisory methods (metodi che forniscono un suggerimento dal programma alla JVM):

  • enableReceiveThreshold

Enables receive threshold, if this feature is supported by the driver. When the receive threshold condition becomes true, a read from the input stream for this port will return immediately. enableReceiveThreshold is an advisory method which the driver may not implement. By default, receive threshold is not enabled. An application can determine whether the driver supports this feature by first calling the enableReceiveThreshold method and then calling the isReceiveThresholdEnabled method. If isReceiveThresholdEnabled still returns false, then receive threshold is not supported by the driver. If the driver does not implement this feature, it will return from blocking reads at an appropriate time.

  • enableReceiveFraming

Enables receive framing, if this feature is supported by the driver. When the receive framing condition becomes true, a read from the input stream for this port will return immediately. enableReceiveFraming is an advisory method which the driver may not implement. By default, receive framing is not enabled. An application can determine whether the driver supports this feature by first calling the enableReceiveFraming method and then calling the isReceiveFramingEnabled method. If isReceiveFramingEnabled still returns false, then receive framing is not supported by the driver. Note: As implemented in this method, framing is not related to bit-level framing at the hardware level, and is not associated with data errors.

  • enableReceiveTimeout

Enables receive timeout, if this feature is supported by the driver. When the receive timeout condition becomes true, a read from the input stream for this port will return immediately. enableReceiveTimeout is an advisory method which the driver may not implement. By default, receive timeout is not enabled. An application can determine whether the driver supports this feature by first calling the enableReceiveTimeout method and then calling the isReceiveTimeout method. If isReceiveTimeout still returns false, then receive timeout is not supported by the driver.

Riferimenti

risposta data 15.08.2018 - 09:01
fonte

Leggi altre domande sui tag