Se ho letto bene, stai parlando del problema affrontato dal pattern Interpreter, ma una sorta di andare in entrambe le direzioni.
Ci sono alcuni modi semplici per ottenere delle belle interfacce generiche, in modo da poter far funzionare il resto della cosa. La mia raccomandazione su che è qualcosa di simile:
public interface Interpreter<OutputType> {
public void setCode(String coding);
public OutputType decode(String formattedData);
public String encode(OutputType rawData); }
Tuttavia, ci sono un paio di ostacoli con implementazioni concrete. Per il tuo esempio di data, potresti dover gestire "9/9/09", "9 settembre 09", "9 settembre 2009". Il primo "tipo" di data è semplice: numeri e simboli di divisori, ma uno degli altri due è piuttosto cattivo. Onestamente, fare qualcosa di totalmente generico (che potrebbe già essere in scatola) probabilmente non è ragionevole, quindi consiglio quanto segue.
Lo attaccherei su due livelli, il primo dei quali è piuttosto semplice con espressioni regolari e stringa di formato: inserire la stringa di dati nelle cose che diventeranno dati non elaborati. Forniresti qualcosa come "D */M */YY" (o "M */D *") per il primo, "D * MMM YY" per il secondo e "Mm + D * e *, YYYY" per l'ultimo, in cui hai definito nei tuoi dati alcuni simboli riservati (D, M, Y, interpretazioni ovvie) e per tutti i tipi di dati (* più caratteri possibili, + "pieno", e caratteri estranei definiti) - questi simboli ovviamente essendo specifico per la tua applicazione. Quindi le tue regex roomp formeranno la stringa, alimentando tutto ciò che è associato a ciascun carattere riservato ai singoli campi di dati e salvando la parte di decorazione (virgole, ecc.) In una stringa di formattazione.
Questo primo livello può essere abbastanza generico: ogni tipo di dati (ad es. Data, coordinate, indirizzo) ha simboli riservati (che non si sovrappongono a nessun carattere di formattazione) e tutti i tipi di dati hanno alcuni simboli condivisi. Forse l'interfaccia Interpreter avrebbe anche i metodi public List<Character> reservedSymbols()
e public void splitCode(List<String> splitcodes)
, o forse i campi garantiti, in modo da poter rendere il divisore una classe esterna e passare i risultati.
Il secondo livello è meno facile, perché raggiunge la parte che non può essere generica. In base al formato dei simboli riservati, i singoli campi devono sapere come presentarsi. Per l'esempio della data, MM direbbe al mese di stampare come (01, 02, ... 12), M * come (1, 2, ... 12), MMM come (JAN, FEB, ... DEC) , Mmm come (Jan, Feb, ... Dec), ecc. Se la tua azienda è stata un po 'coerente o non si avventura troppo lontano dalle rappresentazioni standard di cose, allora la codifica manuale di ciascuna di queste non dovrebbe essere troppo brutta (e infatti, ci sono probabilmente modi intelligenti all'interno di ogni tipo di dati per ridurre il codice replicato). Ma non penso che sia pratico generare tutto questo - voglio dire, praticamente rappresentare quel qualcosa che può essere presentato come un numero o caratteri (come mesi) o interi dati che possono essere dedotti da dati parziali (ad esempio, secolo dall'anno) o come ottenere rappresentazioni troncate dai dati (ad esempio, il troncamento per l'anno è per le ultime due cifre, i numeri più normali che troncano a due cifre iniziali) probabilmente prenderà il tempo necessario per scrivere a mano quei casi, anche se credo di poter Immagina casi della tua applicazione che il trade-off potrebbe valerne la pena. La data è davvero un esempio complicato, ma posso certamente vedere cose ugualmente insidiose in arrivo per altri tipi di dati.
Sommario:
-C'è un volto generico semplice si può mettere sul vostro problema, in modo che il resto della vostra applicazione può essere codificato intorno ad esso.
-questo è un analizzatore di primo passaggio abbastanza semplice e generico, con simboli universali riservati e simboli riservati per ciascun tipo di dati; assicurarsi che questi non si scontrano con i simboli che compariranno nella formattazione
-C'è una fase un po 'noioso finale di codifica per i singoli bit di dati
Nizza domanda, mi piace particolarmente che titolo per il caso generale. – BCS
Grazie a tutti coloro che hanno offerto suggerimenti. Ho finito con una specie di combinatore parser unico. Non è il più elegante, ma ha il compito. La stringa di formato per 38 ° 53 '55.133 "N, 77 ° 02' 15.691" W (ovvero DMS, o gradi minuti secondi) ha finito con $ lat {$ d {} ° $ m {} '$ s {places = 3} "$ h}, $ lon {$ d {} ° $ m {} '$ s {places = 3}" "$ h}. La stringa per 38.898648, -77.037692 (ovvero DD o formato decimale in sei posizioni) $ long {$ dd {places = 6 ~ showNegativeSign = true}}, $ lon {$ dd {places = 6 ~ showNegativeSign = true}} E ovviamente sono possibili una miriade di altre combinazioni, che è quello che cercavo. –