Pracuję nad produktem, w którym jednym z modułów jest parsowanie plików XML i zrzucanie wymaganej zawartości do bazy danych. Mimo że obecnym wymaganiem jest tylko parsowanie plików XML, chcę zaprojektować mój moduł analizujący w taki sposób, aby w przyszłości mógł obsługiwać dowolny rodzaj plików. Powodem takiego podejścia jest to, że budujemy ten produkt dla konkretnego klienta, ale planujemy sprzedać go innym klientom w najbliższej przyszłości. Wszystkie systemy w ekosystemie dla bieżącego klienta wytwarzają i zużywają pliki XML, ale może nie być tak w przypadku innych klientów.
Co do tej pory próbowałem? (Teraźniejszość) Mam na myśli następujący projekt oparty na schemacie strategii. Szybko napisałem kod w eclipse, aby przekazać mój projekt, więc byłoby wspaniale, gdyby inne aspekty, takie jak właściwy sposób obsługi wyjątków, były na razie ignorowane.
Analizator składni : interfejs strategii udostępniający metodę analizy składni.
public interface Parser<T> {
public T parse(String inputFile);
}
* Powodem użycia parametru ogólnego jest umożliwienie dowolnego typu zwrotu, a także zapewnienie bezpieczeństwa typu w czasie kompilacji.
ProductDataXmlParser Konkretna klasa do analizowania pliku product.xml, który zawiera informacje związane z produktem. (przy użyciu 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();
}
}
gdzie : ProductDataTYPE i ProductDataDocument to klasy POJO XMlBean wygenerowane za pomocą polecenia xsd i polecenia scomp.
Przyszłość
Jeśli mam plik product.txt do przeanalizowania w przyszłości, mogę zdefiniować własne POJO o nazwie ProductData, które będzie przechowywać wymaganą zawartość pliku. Następnie mogę utworzyć konkretną klasę o nazwie ProductDataFlatFileFarParser, która implementuje interfejs Parsera, a metoda parsowania wypełnia dla mnie POJO produktu ProductData po przeanalizowaniu pliku.
Czy ten projekt ma sens? Czy są jakieś oczywiste wady w tym projekcie? Na obecnym etapie pozwalam konkretnym klasom zdefiniować algorytm do parsowania pliku, a konkretna klasa decyduje, gdzie wypełnić dane. Wygląda na to, że projekt bardziej zależy od obiektów domeny niż formatów plików. Czy to źle? Wszelkie uwagi dotyczące ulepszenia mojego projektu będą bardzo mile widziane.
Odpowiedzi:
Mam kilka obaw:
Parser<T>
to w zasadzie dobry dźwięk. Widzę dwa potencjalne problemy: (1) zakłada, że dane wejściowe do pliku - na przykład, jeśli próbujesz przeanalizować strumień JSON pobrany z odpowiedzi HTTP? i (2) niekoniecznie zapewnia dużą wartość, z wyjątkiem części większego ogólnego środowiska, w którym masz wiele różnych typów parserów dla wielu różnych typów danych. Ale nie jestem przekonany, że potrzebujesz tak dużych ogólnych ram. Po prostu masz teraz bardzo prosty, konkretny przypadek użycia, o ile mogę powiedzieć: parsuj plik XML na listęProductData
s.ProductDataXmlParser
.RuntimeException
Zamiast tego przekonwertowałbym go na jakiś .źródło
Twój projekt nie jest najlepszą opcją. Według twojego projektu jedyny sposób, aby go użyć:
Z powyższego przykładu nie widzimy zbyt dużych korzyści. Nie możemy robić takich rzeczy:
Zanim zaczniesz szukać ogólnego, możesz rozważyć następujące dwie opcje:
Bez względu na to, skąd pochodzi źródło danych, dane produktu będą miały ten sam format przed zapisaniem ich w bazie danych. Jest to umowa między klientem a usługą zrzutu. Zakładam, że masz te same dane produktu co dane wyjściowe. Możesz po prostu zdefiniować interfejs:
Ponadto definiujesz ProductData jako interfejs, jeśli chcesz, aby był bardziej elastyczny.
Jeśli nie chcesz, aby parser był mieszany z danymi. Możesz podzielić go na dwa interfejsy:
Twój parser będzie wyglądał następująco:
Jeśli dane produktu nie są podobne i chcesz ponownie użyć interfejsu analizatora składni. Możesz to zrobić w ten sposób:
źródło
Na wypadek, gdybyś wolał użyć czegoś już dostępnego, stworzyłem bibliotekę Java o nazwie JRecordBind opartą na XMLSchema (wspieranej przez JAXB).
Urodził się, aby konsumować / produkować pliki o stałej długości, a ponieważ XMLSchema definiuje ich strukturę, możesz używać go ze zwykłym JAXB do marshall / unmarshall plików XML
źródło