Я работаю над продуктом, в котором ответственность одного из модулей состоит в том, чтобы анализировать XML-файлы и выгружать необходимый контент в базу данных. Несмотря на то, что настоящее требование состоит только в разборе файлов XML, я хочу спроектировать свой модуль синтаксического анализа таким образом, чтобы в будущем я мог поддерживать любые типы файлов. Причиной такого подхода является то, что мы создаем этот продукт для конкретного клиента, но планируем продать его другим клиентам в ближайшем будущем. Все системы в экосистеме для текущего клиента производят и потребляют файлы XML, но это может не относиться к другим клиентам.
Что я пробовал до сих пор? (Настоящее время) Я имею в виду следующий дизайн, основанный на шаблоне Стратегии. Я быстро записал код в eclipse, чтобы передать мой дизайн, поэтому было бы замечательно, если другие аспекты, такие как правильный способ обработки исключений, пока игнорируются.
Parser: интерфейс стратегии, который предоставляет метод синтаксического анализа.
public interface Parser<T> {
public T parse(String inputFile);
}
* Причиной использования универсального параметра является разрешение любого возвращаемого типа, а также обеспечение безопасности типов во время компиляции.
ProductDataXmlParser Конкретный класс для анализа файла product.xml, который содержит информацию о продукте. (используя 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();
}
}
где : ProductDataTYPE и ProductDataDocument являются классами XMlBean POJO, созданными с использованием команд xsd и scomp.
Будущее
Если у меня есть файл product.txt для анализа в будущем, я могу определить свой собственный POJO с именем ProductData, который будет содержать необходимое содержимое файла. Затем я могу создать конкретный класс с именем ProductDataFlatFileParser, который реализует интерфейс Parser, и после анализа файла метод parse заполняет для меня ProductData POJO.
Имеет ли этот дизайн смысл? Есть ли очевидные недостатки в этом дизайне? Поскольку проект стоит, я позволяю конкретным классам определять алгоритм для анализа файла и позволяю конкретному классу решать, где заполнять данные. Кажется, что дизайн больше зависит от объектов домена, а не от форматов файлов. Это плохая вещь? Будем очень благодарны за любые отзывы о том, как я могу улучшить свой дизайн.
Ответы:
У меня есть пара проблем:
Parser<T>
это в основном звук. Я вижу две потенциальные проблемы: (1) он предполагает ввод файла - что, если вы пытаетесь проанализировать поток JSON, полученный, например, из ответа HTTP? и (2) он не обязательно обеспечивает большую ценность, за исключением того, что является частью более крупной универсальной структуры, где у вас есть много разных типов синтаксических анализаторов для множества разных типов данных. Но я не уверен, что вам нужны такие большие общие рамки. Насколько я могу судить, сейчас у вас есть очень простой, конкретный вариант использования: разобрать файл XML в списокProductData
s.ProductDataXmlParser
. Я бы преобразовал это в какой-то типRuntimeException
.источник
Ваш дизайн не лучший вариант. По твоему замыслу единственный способ его использования:
Мы не видим слишком много пользы от приведенного выше примера. Мы не можем делать такие вещи:
Вы можете рассмотреть следующие два варианта, прежде чем искать универсальный:
Независимо от источника данных, данные о продукте будут иметь одинаковый формат перед сохранением в базе данных. Это контракт между клиентом и вашим сервисом. Поэтому я предполагаю, что у вас есть тот же ProductData, что и на выходе. Вы можете просто определить интерфейс:
Более того, вы определяете ProductData как интерфейс, если хотите, чтобы он был более гибким.
Если вы не хотите, чтобы парсер смешивался с данными. Вы можете разделить его на два интерфейса:
И ваш парсер будет выглядеть так:
Если ProductData не похожи, и вы хотите повторно использовать интерфейс Parser. Вы можете сделать это следующим образом:
источник
На всякий случай, если вы предпочитаете использовать что-то уже доступное, я создал библиотеку java под названием JRecordBind , основанную на XMLSchema (при поддержке JAXB).
Он был создан для того, чтобы потреблять / производить файлы фиксированной длины, и, поскольку XMLSchema определяет их структуру, вы можете использовать его с простым JAXB для маршалирования / деинсталляции XML-файлов.
источник