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


12

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

L'app comunica con un server API scritto in Python .

Il server Python comunica con un database SQL .

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

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

Ad esempio, un Usertipo potrebbe assomigliare a questo (pseudocodice):

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

Ogni parte del progetto avrebbe bisogno di un qualche tipo di rappresentazione per User. Le parti Java e Python avrebbero bisogno di due diverse classdichiarazioni. Il database avrebbe bisogno di una Userdichiarazione di tabella. E anche il sito di front-end dovrebbe rappresentare un User.

Ripetendo questo tipo 4 volte diverse si rompe davvero il principio Don't Repeat-Yourself . Inoltre c'è il problema che se il Usertipo viene modificato, questi cambiamenti devono essere ripetuti in ogni diversa parte del progetto.

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

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


Questo è uno dei motivi per cui molte persone hanno spostato tutto il loro sviluppo su JavaScript. Funziona sul client (web, ionico per mobile, elettrone per desktop), server (nodo), database (MongoDB).
Paul

3
Si possono condividere le stesse strutture di dati se il back-end e il front-end usano la stessa lingua. Non ti stai ripetendo se utilizza basi di codice diverse. Utilizzare gli strumenti per generare le classi dagli schemi xml o dalle stringhe Json dalle diverse piattaforme di sviluppo.
Jon Raynor,

5
Repeating this type 4 different times really breaks the Don't-Repeat-Yourself principle. Non lo fa. Hai 4 sistemi diversi che fanno cose diverse. Stai portando DRY troppo lontano. Secondo la mia esperienza, il tipo di riusabilità che vuoi fare è il seme del male, perché introduce uno stretto accoppiamento. È ancora peggio che averlo ripetuto User4 volte in 4 lingue diverse. In ambienti distribuiti, l'accoppiamento è un problema. DRY no.
Laiv

Non hai tempo per una risposta: a seconda delle tue esigenze potresti provare a formulare le regole per la validazione usando ad esempio OWL (quindi costruisci un'ontologia). Le regole di convalida diventano quindi "dati" che possono essere utilizzati nei punti necessari. La modifica delle regole può quindi essere eseguita in un punto centrale.
Daniel Jour,

Risposte:


12

Tu non. O davvero, non dovresti.

Se pensi all'app, al tuo server e al tuo sito web come contesti separati, allora ha senso che ci siano strutture duplicate. Ragioni 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à forti 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 in tutti
  • Le strutture condivise diventano una dipendenza, che deve essere gestita. Avere una dipendenza condivisa complica notevolmente lo sviluppo, dato che il cambiamento che è grande in un contesto è spaventoso in un altro. Sono quindi necessari molti sforzi 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ò comunque succedere che una nuova versione di un contesto sia distribuita mentre altre sono sulla vecchia versione, quindi le situazioni in cui è presente la desincronizzazione nelle versioni devono ancora essere indirizzato

Sebbene il principio DRY sia sorprendente, penso che condividere le strutture di dati tra contesti o livelli crei più problemi di quanti ne risolva. Soprattutto se il progetto diventa abbastanza grande da permettere a persone diverse di lavorare in contesti diversi.


5

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

Trova la forma canonica dei dati

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

Deriva (automaticamente) le altre forme da esso

Successivamente, escogita un modo per generare tutte le altre forme da quella canonica. Ad esempio, supponendo che la tua forma canonica sia lo schema SQL, puoi generare facilmente codice JavaScript, Java e Python (SQL viene facilmente analizzato e un buon candidato per l'origine canonica).

Accetta le differenze

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

Tuttavia, se è possibile, evitare tale duplicazione. È una PITA, anche se la maggior parte del codice viene generata automaticamente.


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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.