Sto scrivendo un servizio web in Java che legge alcune informazioni da un DB e genera più file JSON scritti su S3. Per ogni tipo di file, ho un POJO che è serializzato su JSON usando jackson.
Lo schema dei file può cambiare nel tempo: è possibile aggiungere nuovi campi, rimuovere campi esistenti, ecc. Qualsiasi modifica dello schema richiederà una nuova versione del file da creare. Pertanto, in qualsiasi momento, potrebbero esserci più versioni di un file in S3.
L'architettura attuale è piuttosto semplice - Esiste una classe Controller che chiama un paio di classi per ottenere dati dal DB. Dopo di ciò passa quei dati a una classe FileGenerator che crea più POJO e li scrive su S3 attraverso una classe di repository.
Devo modificare questo design per renderlo più modulare e gestire più versioni di file.
Finora questo è quello che ho trovato:
-
Una classe generatore per generare ogni tipo di file (o POJO) (File1Generator, File2Generator ecc.)
-
Una classe FileManager per ogni tipo di file, che chiama il generatore e serializza il POJO e quindi lo scrive nell'archivio dati. (File1Manager, File2Manager ecc.)
-
La classe Controller ora raggrupperà tutti i file manager uno per uno.
Tuttavia, non sono sicuro di come progettare il sistema in modo da poter gestire più versioni dei file. Per i POJO, devo avere un POJO distinto per ogni versione: File1POJO_V1, File1POJO_V2. Ma poi avrò anche generatori aggiuntivi e gestori aggiuntivi. Le informazioni trasmesse ai generatori possono variare da una versione all'altra. Lo stesso con i gestori. Sto facendo fatica a creare una buona gerarchia di classi tale che il codice sia facilmente estensibile. Di seguito è riportato uno scheletro del codice, come ho pensato:
class File1POJOV1{
private String prop1;
private String prop1;
..........
public setProp1(){}
public setProp2(){}
}
class File1Generator_V1{
public File1POJOV1 createFile(String prop1, String prop2 ...){
//Perform manipulations and create File1POJO_V1
}
}
class File1Manager_V1{
private File1Generator_V1 fileGenerator;
private Serializer serializer; //JSON serializer
public void createFile(String prop1, String prop2,.., String directory){
File1POJOV1 file = fileGenerator.createFile(prop1, prop2 ...);
byte[] data = serializer.serialzer(data);
String path = generateFilePath(); //dynamic based on properties
writeToS3(data, path, directory); //write data to S3 bucket
}
}
class Controller{
File1Manager_V1 manager1_V1;
File2Manager_V1 manager2_V1;
generateFile(String prop1, prop1..., directory){
manager1.createFile(prop1, prop2..,directory);
manager2.createFile(prop3, prop4.. directory)
}
}
Il problema è che quando c'è una nuova versione di un file, ci sarà un POJO separato per quello che avrà più (o meno) campi rispetto alla versione precedente. Questa modifica verrà propagata ai Generatori e ai Manager man mano che i parametri di input dei metodi cambieranno. Non sono in grado di capire come avere un design elegante per questo sistema che semplifica la manutenzione.
Modifica : Ho alcuni buoni suggerimenti per non rimuovere campi nelle versioni successive di un file. Ma la mia domanda rimane: supponendo che non rimuovo i campi e che ogni nuova versione sia una sottoclasse di quella precedente, dovrò comunque scrivere un generatore separato e un gestore per ciascuna sottoclasse. Questo può essere evitato? Quale sarebbe un design migliore?