Je travaille sur un produit dans lequel la responsabilité de l'un des modules est d'analyser les fichiers XML et de vider le contenu requis dans une base de données. Même si la présente exigence consiste uniquement à analyser des fichiers XML, je souhaite concevoir mon module d'analyse de manière à pouvoir prendre en charge tout type de fichiers à l'avenir. La raison de cette approche est que nous construisons ce produit pour un client spécifique mais prévoyons de le vendre à d'autres clients dans un proche avenir. Tous les systèmes de l'écosystème pour le client actuel produisent et consomment des fichiers XML mais cela peut ne pas être le cas pour d'autres clients.
Qu'est-ce que j'ai essayé jusqu'à présent? (Le présent) J'ai à l'esprit la conception suivante qui est basée sur le modèle de stratégie. J'ai rapidement écrit le code dans eclipse pour transmettre ma conception, donc ce serait génial si d'autres aspects tels que la bonne façon de gérer les exceptions étaient ignorés pour l'instant.
Analyseur: interface de stratégie qui expose une méthode d'analyse.
public interface Parser<T> {
public T parse(String inputFile);
}
* La raison d'utiliser un paramètre générique est d'autoriser tout type de retour et d'assurer la sécurité du type au moment de la compilation.
ProductDataXmlParser Une classe concrète pour analyser un fichier product.xml qui contient des informations relatives au produit. (en utilisant XMLBeans)
public class ProductDataXmlParser implements Parser<ProductDataTYPE> {
public ProductDataTYPE parse(String inputFile) {
ProductDataTYPE productDataDoc = null;
File inputXMLFile = new File(inputFile);
try {
productDataDoc = ProductDataDocument.Factory.parse(inputXMLFile);
} catch(XmlException e) {
System.out.println("XmlException while parsing file : "+inputXMLFile);
} catch(IOException e) {
System.out.println("IOException while parsing file : "+inputXMLFile);
}
return productDataDoc.getProductData();
}
}
où : ProductDataTYPE et ProductDataDocument sont des classes POJO XMlBean générées à l'aide d'un xsd et de la commande scomp.
L'avenir
Si j'ai un fichier product.txt à analyser à l'avenir, je peux définir mon propre POJO appelé ProductData qui contiendra le contenu requis du fichier. Je peux ensuite créer une classe concrète appelée ProductDataFlatFileParser qui implémente l'interface Parser et demander à la méthode d'analyse de remplir le ProductData POJO pour moi après avoir analysé le fichier.
Cette conception a-t-elle un sens? Y a-t-il des défauts évidents dans cette conception? Dans l'état actuel de la conception, j'autorise les classes concrètes à définir l'algorithme pour analyser un fichier et je laisse la classe concrète décider où remplir les données. La conception semble être plus dépendante des objets de domaine plutôt que des formats de fichiers. Est-ce une mauvaise chose? Toute contribution sur la façon dont je peux améliorer ma conception sera très appréciée.
Réponses:
J'ai quelques inquiétudes:
Parser<T>
c'est fondamentalement sain. Je vois deux problèmes potentiels: (1) il suppose une entrée de fichier - et si vous essayez d'analyser un flux JSON que vous avez récupéré d'une réponse HTTP, par exemple? et (2) il ne fournit pas nécessairement beaucoup de valeur, sauf dans le cadre d'un cadre générique plus large où vous avez beaucoup de différents types d'analyseurs pour de nombreux types de données différents. Mais je ne suis pas convaincu que vous ayez besoin d'un tel grand cadre générique. Vous avez juste un cas d'utilisation très simple et concret pour autant que je sache: analyser un fichier XML dans une liste deProductData
s.ProductDataXmlParser
. Je le convertirais plutôt en une sorteRuntimeException
.la source
Votre conception n'est pas une meilleure option. Par votre conception, la seule façon de l'utiliser:
Nous ne pouvons pas voir trop d'avantages de l'exemple ci-dessus. Nous ne pouvons pas faire des choses comme ça:
Vous pouvez envisager les deux options suivantes avant de rechercher le générique:
Peu importe d'où vient la source de données, les données du produit seront au même format avant de les enregistrer dans la base de données. C'est le contrat entre le client et votre service de vidage. Je suppose donc que vous avez les mêmes ProductData en sortie. Vous pouvez simplement définir une interface:
De plus, vous définissez ProductData comme interface si vous le souhaitez plus flexible.
Si vous ne voulez pas que l'analyseur soit mélangé avec les données. Vous pouvez le diviser en deux interfaces:
Et votre analyseur ressemblera à ceci:
Si le ProductData n'est pas similaire et que vous souhaitez réutiliser l'interface Parser. Vous pouvez le faire de cette façon:
la source
Juste au cas où vous préféreriez utiliser quelque chose déjà disponible, j'ai créé une bibliothèque java appelée JRecordBind qui est basée sur XMLSchema (soutenu par JAXB).
Il est né pour consommer / produire des fichiers de longueur fixe et, puisque XMLSchema définit leur structure, vous pouvez l'utiliser avec du JAXB simple pour rassembler / dé-marshaller des fichiers XML
la source