Come evitare la duplicazione delle strutture dati quando parti di un'app sono scritte in lingue diverse?

12

Ad esempio, supponi di scrivere un'app in Java .

La tua app comunica con un server API scritto in Python .

Il server Python comunica con un SQL database.

Hai anche un sito web per la tua app scritto in JavaScript .

Con 4 lingue diverse, è facile finire per ripetere essenzialmente le stesse strutture di dati 4 volte diverse.

Ad esempio, un tipo User potrebbe apparire come questo (pseudocodice):

type User {
  integer id;
  string name;
  timestamp birthday;
}

Ogni parte del progetto richiederebbe un qualche tipo di rappresentazione per User . Le parti Java e Python necessiterebbero di due diverse dichiarazioni class . Il database avrebbe bisogno di una dichiarazione della tabella User . E il sito di front-end dovrebbe rappresentare anche un User .

La ripetizione di questo tipo 4 volte differenti infrange il principio Don't-Repeat-Yourself . Inoltre, vi è il problema che se il tipo User viene modificato, è necessario ripetere queste modifiche in ogni parte diversa del progetto.

So che la libreria protobuf di Google offre una sorta di soluzione a questo problema in cui si scrive una struttura dati utilizzando una sintassi speciale e quindi la libreria genera una dichiarazione di struttura per te in più linguaggi di programmazione diversi. Ma questo ancora non affronta il problema di dover ripetere la logica di validazione per i tuoi tipi.

Qualcuno ha suggerimenti o link a libri / post di blog su questo?

    
posta Normangorman 09.02.2018 - 02:18
fonte

2 risposte

12

Non lo fai. O davvero, non dovresti.

Se pensi all'app, al tuo server e al tuo sito web come contesti separati, allora ha senso esserci strutture duplicate. Motivi per cui potrebbe essere una buona cosa:

  • Le strutture sono simili, ma non uguali. Anche se il 90% della struttura è uguale in tutti i contesti. È il 10% che ti darà enormi mal di testa.
  • I modelli e le implementazioni potrebbero essere diversi. Quando vengono utilizzati linguaggi e framework diversi, diventa troppo difficile avere la stessa implementazione su tutti loro
  • Le strutture condivise diventano una dipendenza, che deve essere gestita. Avere una dipendenza condivisa complica enormemente lo sviluppo, in quanto il cambiamento che è grande in un contesto è abissale in un altro. Quindi è necessario un grande sforzo per coordinare lo sviluppo di questa dipendenza condivisa
  • Contesti diversi hanno distribuzioni diverse. Anche se riesci a condividere le stesse strutture di dati e lo stesso codice di convalida in tutti i contesti, può ancora succedere che venga distribuita la nuova versione di un contesto mentre altri sono in versione precedente, quindi le situazioni in cui è presente la desincronizzazione nelle versioni devono ancora essere indirizzato

Sebbene il principio di DRY sia sorprendente, penso che condividere le strutture di dati attraverso contesti o livelli crea più problemi di quanti ne risolva. Soprattutto se il progetto cresce abbastanza da far lavorare persone diverse su contesti diversi.

    
risposta data 09.02.2018 - 06:25
fonte
5

Penso che @Euphoric abbia elencato un paio di buoni motivi per non duplicare il tuo codice. Tuttavia, se devi farlo, ti consigliamo di utilizzare la generazione del codice.

Trova la forma canonica dei dati

Per farlo efficacemente devi prima scoprire qual è la forma canonica dei dati. È il tuo schema SQL, o classi nel tuo programma Java?

Ricava (automaticamente) gli altri moduli da esso

Dopodiché, escogitare un modo per generare tutte le altre forme da quella canonica. Ad esempio, supponendo che la forma canonica sia lo schema SQL, è possibile generare facilmente codice JavaScript, Java e Python (SQL viene facilmente analizzato e un buon candidato per la fonte canonica).

Accoglie le differenze

Dovrebbe essere facile contrassegnare le sezioni del codice generato come "non toccare" - in questo modo si accolgono le differenze richieste tra tutte le diverse rappresentazioni (ad esempio: il codice personalizzato che hai scritto per il frontend JS e Java backend) che devono essere preservati attraverso le rigenerazioni.
Prendi un esempio da Git; quando apre un editor per farti inserire un messaggio di commit il file contiene già del testo, ma ha il marcatore # -------- >8 -------- per sapere dove finisce il contenuto tuo e dove il suo inizia il testo generato automaticamente.

Tuttavia, se puoi, evita tale duplicazione. È un PITA, anche se la maggior parte del tuo codice viene generato automaticamente.

Questa risposta è un po 'di una storia invece di "ecco alcune buone pratiche" una: quello che ho descritto è esattamente quello che ho fatto una volta quando ho avuto lo stesso problema di te e avevo bisogno di avere gli stessi dati rappresentati in parti diverse del sistema (o, piuttosto, in due sistemi diversi).

    
risposta data 09.02.2018 - 08:28
fonte

Leggi altre domande sui tag