Migliore approccio per l'analisi dell'inserimento in più scenari

2

Sto sviluppando un'API con una chiamata che accetta un grande oggetto JSON.

In base a questo oggetto, esistono 10 possibili scenari di analisi, ad esempio se il campo xxxx.xxx è presente, andare con lo scenario 5.

Attualmente abbiamo circa 10 se le istruzioni in una funzione di controllo di oltre 200 linee, che decide quale scenario scegliere. La complessità ciclomatica è superiore a 5000 e la complessità di nPath è superiore a 10 milioni

Poiché non è scalabile, ho finalmente trovato il tempo di rifattorizzarlo e renderlo più liberamente abbinato

Quale sarebbe il miglior schema di progettazione possibile per questo caso?

Stavo pensando di avere più classi parser che faccio il ciclo e ognuna di esse ha una funzione chiamata canHandle ($ jsonObject), e se alcuni campi sono presenti, canHandle restituirà true e quella classe può quindi fare la sua logica.

È simile al modello di strategia?

Altro sfondo:

È uno strumento di prenotazione per i viaggi da punto a punto.

Quindi, dire che voglio viaggiare da un aeroporto a una stazione ferroviaria, il JSON avrebbe i seguenti campi:

route.pickuppoint.airport.iata
route.dropoffpoint.trainstation.id

Esistono più entità che possono esistere in pickuppoint e dropoffpoint (stazioni / aeroporti / indirizzi / numeri di volo) e devono essere analizzate in modo diverso nel nostro database

Quindi se qualcuno chiama l'API con un aeroporto nel pickup, devo analizzare l'aeroporto e tradurlo in un indirizzo usando alcune API esterne e inserirlo nel DB, lo stesso vale per le altre entità

Esempio di codice:

if (isset($data['Address']['Street'])) {
        // Parse address
    } elseif (isset($data['Location']['Latitude'])) {
        // Parse Location
    } elseif (isset($data['Airport']['Id'])) {
        // Parse airport
    } elseif (isset($data['Flight']['FlightNumber'])) {
        // Resolve flight number and parse
    } elseif (isset($data['Trainstation']['id'])) {
        // Resolve train station
    }

Come puoi immaginare, se dovessimo aggiungere più opzioni, questo codice sarebbe solo più brutto

    
posta Mazzy 06.02.2017 - 16:00
fonte

2 risposte

1

Può ogni pezzo di ode che crea il JSON in questione aggiungere un marcatore uniforme e univoco per il tipo di informazioni che produce?

Si consideri:

kind = $data['kind']  // always present.
if (kind == POSTAL_ADDRESS) {
  ...
} 
else if (kind == COORDINATES) {
  ...
}
// etc
    
risposta data 07.02.2017 - 17:08
fonte
0

Ecco un approccio generale: scrivere ogni parser come una funzione in un dominio appropriato che può fallire. Tenderei a utilizzare un valore di ritorno Optional per segnalare un errore, ma potrebbe essere più comodo utilizzare le eccezioni a seconda della lingua / situazione. Avresti quindi

parser1 : JSON -> Optional[Type1]
parser2 : JSON -> Optional[Type2]
...
parserA : JSON -> Optional[TypeA]

E poi scrivi

parser : JSON -> Optional[Type1 | Type2 | ... | TypeA]
parser json = parser1(json).or(parser2(json))...or(parserA(json))

La ragione per cui penso che sia preferibile utilizzare le funzioni canHandle è che questi tipi di guardie tendono a introdurre la duplicazione tra il controllo e l'esecuzione (ad esempio il tuo canHandle deve controllare gli stessi percorsi esistenti da ciò che legge il parser) , introduce l'accoppiamento temporale nei tuoi consumatori (il tuo consumatore deve ricordarsi di controllare sempre canHandle prima dell'analisi) e spesso porta a cicli sprecati ( canHandle esegue un lavoro di analisi preliminare da solo).

Se la domanda è quale modello si adatta qui, allora sono d'accordo che un modello di strategia è appropriato.

    
risposta data 09.04.2017 - 18:45
fonte

Leggi altre domande sui tag