Builder, Factory oui c'est un peu pareil.
Mais tu ne dis pas tout sur ton fichier.
Par exemple, je ne vois pas comment tu sais de quel attribut il s'agit quand tu lis une ligne de ton fichier. Il te faut le nom de l'attribut + le nom de la classe + la valeur elle-même.
Si ta ligne est toujours découpée de la même manière du genre :
valeur;nom attribut;nom classe
Il faut des factory/builder par classe comme tu as fait.
Il faut un mécanisme générique qui lui fait la lecture de la ligne et récupère les 3 infos genre dans une StructuredLine qui comporte les données value,attribute,class.
Chaque Builder/Factory est enregistré dans un dictionnaire ( ~ Hashtable) et la clé de recherche pour chaque Builder est le nom de la classe. Ainsi ton mécanisme de lecture peut récupérer le Builder en fonction de la ligne qu'il vient de récupérer.
Ex : Builder *builder =builderDictionary->getBuilder(structuredLine->getClassName());
Au final, tu as un truc du genre (j'ai fait un truc résumé et pour la syntaxe C++, ça fait hyper longtemps que je n'en ai pas écrit donc....) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| struct StructuredLine {
char *value;
char *attribute;
char *className;
}
// Utilisé pour stocker tous les objets créés lors de la lecture du fichier
struct ObjectList {
}
initDictionary(BuilderDictionary *dictionary) {
dictionary->register("Class1",new Class1Builder());
dictionary->register("Class2",new Class2Builder());
dictionary->register("Class3",new Class3Builder());
...
}
readObjectFile(int fd,ObjectList *objectList,BuilderDictionary *dictionary) {
void *currentObject = null;
char *line = null;
char *currentClassName = null;
StructuredLine structuredLine;
while (!fin du fichier) {
line = readline(fd);
if (line!=null) {
// Split de la ligne pour remplir structuredLine
...
Builder *builder = dictionary->getBuilder(structuredLine.className);
// On part du principe que tous les objets ont un builder sinon, il faut gérer en plus ce cas.
if (currentClassName==null || strcmp(currentClassName,structuredLine.className)!=0) {
// Nouvel objet à créer
if (currentObject!=null)
objectList->addObject(currentObject);
currentObject=null;
currentObject = builder->createObject();
}
// Chaque builder réel (sous classe de Builder) sait quoi affecter en fonction du nom de l'attribut lu. Il comporte, le builder, une série de strcmp pour tester les nom des attributs dans sa méthode "set"
builder->set(currentObject,structuredLine);
}
else {
// Fin du fichier, ne pas oublier le dernier objet non ajouté
if (currentObject!=null)
objectList->addObject(currentObject);
// positionner "fin du fichier"
}
}
} |
Partager