Estratto meglio? Creazione di stringhe basate sui dati

0

Sto tentando di postare questa domanda in modo neutrale rispetto al linguaggio di programmazione, in modo da aiutare il pubblico più vasto. Ma per quelli che devono sapere, sto usando i framework Objective-C e iOS.

Lo sfondo:

Ho una stringa di formato che descrive il valore finale di un attributo, che è anche una stringa. Esempio: il nome attributo di "report1" potrebbe avere il formato di:

"[chefName] has [totalOrders]"

Posso avere diversi attributi di questo tipo con formati diversi. Questi formati sono centralizzati in un file di dati. Il mio desiderio è che i futuri sviluppatori aggiornino questo file di dati solo per modificare il comportamento del codice.

Consegno il formato a un parser che restituisce una serie di dizionari di singoli elementi che descrivono come gestire ciascun elemento del formato. Per continuare l'esempio:

[ {"chefName": "directive"},
  {" has ": "literal"},
  {"totalOrders": "directive"}]

Quindi elaborerò ciascun elemento dell'array per comporre il valore finale. Qualsiasi cosa taggata "letterale" viene semplicemente aggiunta al valore finale della stringa. Qualsiasi cosa taggata "direttiva" viene cercata in una tabella di distribuzione (dizionario) di funzioni e il valore di ritorno di tale funzione viene aggiunto al valore di stringa finale.

Ad esempio: una funzione sul tasto della tabella di invio "totalOrders" potrebbe anche essere chiamata totalOrders () e restituire "12" come stringa.

Altri dettagli che portano alla mia domanda:

Per molte funzioni nella tabella di spedizione, ovviamente sanno come calcolare e restituire il valore appropriato. Tuttavia, per alcuni elementi, è il chiamante della funzione che conosce meglio il valore.

Esempio continuativo: supponiamo che collectInfo () sia una funzione che esegue il ciclo attraverso l'array di dizionari analizzati in formato. Potrebbe sapere quale dovrebbe essere il valore di ritorno di chefName () anche se non ha idea di cosa dovrebbe essere totalOrders ().

Ecco come ho risolto questo problema. Ogni funzione nella tabella di invio accetta un argomento. Alcune funzioni si limitano a restituire l'argomento che viene loro fornito. Prima di chiamare una funzione, il chiamante cerca la chiave dal dizionario nel altro dizionario che ha. Se c'è una corrispondenza, passa in quel valore.

Esempio: collectInfo () ha un dizionario chiamato "specialX" che assomiglia a questo:

{"chefName": lookupChef(c)}

"c" è una variabile locale di collectInfo () a cui la funzione chefName () non sarebbe a conoscenza. Quindi ciò che collectInfo () fa è call lookupChef (c) e passa il valore restituito a chefName () in questo modo:

chefName(lookupChef(c))

E l'intero codice per chefName () è:

chefName(x) {
    return x
}

Ciò consente al mio codice di essere ancora (principalmente) guidato dai dati. Non devo includere if / then confronti tra stringhe e cose hard code come "chefName" nel mio loop in collectInfo ().

Quindi ecco i miei problemi con questa soluzione:

  1. Ho ancora quel dizionario "specialeX" codificato su collectInfo (). Questo uccide il mio approccio puramente guidato dai dati. Sto riscontrando problemi nell'estrazione di un file di dati. Non sono sicuro che potrei mai.
  2. C'è un modo in cui posso creare la funzione chefName () in modo che sappia cosa deve sapere per calcolare la risposta? Cioè, c'è un modo per dirlo di lookupChef (c) direttamente senza interrompere l'incapsulamento?
  3. Dopo aver analizzato il formato, forse c'è un approccio migliore interamente alla composizione del valore finale?

Un'ultima nota.

Ci si potrebbe chiedere da dove provenga la tabella di spedizione e le funzioni al suo interno. Questo è l'altro file che gli sviluppatori futuri aggiorneranno se viene aggiunto un nuovo elemento. Ad esempio, se viene aggiunto un nuovo elemento di formato "[quantityOfButtons]", è necessario aggiungere una nuova voce nella tabella di distribuzione e una nuova funzione corrispondente.

Il file in cui collectInfo () è definito importa il file in cui sono definiti la tabella di distribuzione e le sue funzioni.

    
posta Jeff 28.01.2015 - 16:00
fonte

1 risposta

1

Sembra che il punto cruciale del problema sia:

For a lot of functions in the dispatch table, they obviously know best how to calculate and return the appropriate value. However, for a few items, it is the caller of the function who best knows the value.

Quale soluzione dovresti utilizzare dipende interamente da perché il chiamante conosce meglio , che non hai spiegato. Ma probabilmente si ridurrebbe a questo: a prescindere dalla cosa speciale a cui ha accesso collectInfo (), dovrebbe assegnarlo alle funzioni della tabella di invio . Quindi chefName () può accedere alla cosa speciale stessa invece di affidarsi a specialX per fornire lookupChef ().

Senza sapere esattamente qual è la cosa speciale e perché le funzioni non hanno già accesso ad essa, posso solo suggerire le opzioni ovvie come passare ad ogni funzione come parametro (dato che sembrano tutte essere 0-ary in questo momento) o passarlo al costruttore del dispatch table (se è il tipo di cosa che ha bisogno di essere costruito).

Per quanto riguarda la terza domanda, sembra che quello che stai facendo ora sia guardare un "elemento" (dizionario a chiave singola), ottenere il valore a cui si riferisce, quindi semplicemente aggiungere quel valore alla stringa finale. Probabilmente va bene, ma se senti il bisogno di migliorarlo, ti suggerirei di mantenere i valori in un array finché non li hai recuperati tutti, quindi concatenando tutto in seguito.

I vantaggi sono che gli elementi possono essere elaborati in qualsiasi ordine (anche in parallelo), ed è molto facile fare una logica di validazione o formattazione sui valori prima di convertirli tutti in stringhe. Ad esempio, potresti verificare che totalOrders sia un numero, quindi aggiungere <font color="red"></font> se il numero è inferiore a 10.

    
risposta data 29.01.2015 - 21:03
fonte

Leggi altre domande sui tag