Saya sedang mengerjakan suatu produk di mana tanggung jawab salah satu modul adalah mem-parsing file XML dan membuang konten yang diperlukan dalam database. Meskipun persyaratan saat ini hanya untuk mem-parsing file XML, saya ingin merancang modul parsing saya dengan cara yang saya dapat mendukung semua jenis file di masa depan. Alasan untuk pendekatan ini adalah bahwa kami sedang membangun produk ini untuk klien tertentu tetapi berencana untuk menjualnya ke klien lain dalam waktu dekat. Semua sistem dalam ekosistem untuk klien saat ini menghasilkan dan menggunakan file XML tetapi ini mungkin tidak berlaku untuk klien lain.
Apa yang sudah saya coba sejauh ini? (Hadiah) Saya memiliki desain berikut dalam pikiran yang didasarkan pada pola Strategi. Saya telah dengan cepat menuliskan kode dalam gerhana untuk menyampaikan desain saya sehingga akan lebih bagus jika aspek-aspek lain seperti cara penanganan pengecualian yang tepat diabaikan untuk saat ini.
Parser: Antarmuka strategi yang memperlihatkan metode parse.
public interface Parser<T> {
public T parse(String inputFile);
}
* Alasan untuk menggunakan parameter generik adalah untuk memungkinkan semua jenis pengembalian serta memastikan keamanan jenis pada waktu kompilasi.
ProductDataXmlParser Kelas konkret untuk mem-parsing file product.xml yang berisi informasi terkait produk. (menggunakan 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();
}
}
di mana : ProductDataTYPE dan ProductDataDocument adalah kelas XMlBean POJO yang dihasilkan menggunakan xsd dan perintah scomp.
Masa depan
Jika saya memiliki file product.txt untuk diuraikan di masa mendatang, saya dapat menentukan POJO saya sendiri yang disebut ProductData yang akan menampung konten yang diperlukan dari file tersebut. Saya kemudian dapat membuat kelas konkret yang disebut ProductDataFlatFileParser yang mengimplementasikan antarmuka Parser dan meminta metode parse mengisi POJO ProductData untuk saya setelah mem-parsing file.
Apakah desain ini masuk akal? Apakah ada kekurangan yang jelas dalam desain ini? Sebagai desain berdiri, saya membiarkan kelas beton untuk mendefinisikan algoritma untuk mem-parsing file dan membiarkan kelas beton memutuskan di mana mengisi data. Desain tampaknya lebih bergantung pada objek domain daripada format file. Apakah ini hal yang buruk? Setiap masukan tentang bagaimana saya dapat meningkatkan desain saya akan sangat dihargai.
Jawaban:
Saya memiliki beberapa masalah:
Parser<T>
pada dasarnya suara. Saya memang melihat dua masalah potensial: (1) mengasumsikan input file - bagaimana jika Anda mencoba mengurai aliran JSON yang Anda ambil dari respons HTTP, misalnya? dan (2) itu tidak selalu memberikan banyak nilai kecuali sebagai bagian dari beberapa kerangka kerja generik yang lebih besar di mana Anda memiliki banyak jenis parser yang berbeda untuk banyak jenis data yang berbeda. Tapi saya tidak yakin Anda membutuhkan kerangka kerja generik yang begitu besar. Anda hanya memiliki case use yang sangat sederhana dan konkret sekarang, sejauh yang saya tahu: parsing file XML ke dalam daftarProductData
s.ProductDataXmlParser
. Saya akan mengubahnya menjadi semacamRuntimeException
gantinya.sumber
Desain Anda bukan pilihan terbaik. Dengan desain Anda, satu-satunya cara untuk menggunakannya:
Kita tidak dapat melihat terlalu banyak manfaat dari contoh di atas. Kami tidak dapat melakukan hal-hal seperti ini:
Anda dapat mempertimbangkan dua opsi berikut sebelum mencari yang umum:
Tidak masalah dari mana sumber data berasal, data produk akan memiliki format yang sama sebelum Anda menyimpannya ke basis data. Ini adalah kontrak antara klien dan layanan pembuangan Anda. Jadi saya menganggap Anda memiliki ProductData yang sama dengan output. Anda cukup mendefinisikan antarmuka:
Selain itu Anda mendefinisikan ProductData sebagai antarmuka jika Anda ingin lebih fleksibel.
Jika Anda tidak ingin Parser dicampur dengan data. Anda dapat membaginya menjadi dua antarmuka:
Dan parser Anda akan terlihat seperti ini:
Jika ProductData tidak serupa dan Anda ingin menggunakan kembali antarmuka Parser. Anda bisa melakukannya dengan cara ini:
sumber
Kalau-kalau Anda lebih suka menggunakan sesuatu yang sudah tersedia, saya telah membuat perpustakaan java bernama JRecordBind yang didasarkan pada XMLSchema (didukung oleh JAXB).
Itu lahir untuk mengkonsumsi / menghasilkan file dengan panjang tetap, dan, karena XMLSchema mendefinisikan struktur mereka, Anda dapat menggunakannya dengan JAXB biasa untuk marshall / unmarshall file XML
sumber