How does the parser file design in java take place through the strategy pattern?

442    Asked by AngelaBaker in Java , Asked on Oct 10, 2022

I am working on a product in which the responsibility of one of the modules is to parse XML files and dump the required content in a database. Even though the present requirement is only to parse XML files, I want to design my parsing module in a fashion that I can support any kind of files in the future. The reason for this approach is that we are building this product for a specific client but plan to sell it to other clients in the near future. All the systems in the ecosystem for the current client produce and consume XML files but this may not be the case for other clients.


What have I tried so far? (The Present) I have the following design in mind which is based on the Strategy pattern. I have quickly written down the code in eclipse to convey my design so it would be great if other aspects such as proper way of handling exceptions are ignored for now.


Parser : The strategy interface that exposes a parse method.


 public interface Parser {
        public T parse(String inputFile);
    }
*The reason for using a generic parameter is to allow any return type as well as ensure type safety at compile time.
ProductDataXmlParser A concrete class for parsing a product.xml file that contains product related information. (using XMLBeans)
public class ProductDataXmlParser implements Parser {
    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();
    }

where : ProductDataTYPE and ProductDataDocument are XMlBean POJO classes generated using an xsd and the scomp command.


The future

If I have a product.txt file to be parsed in the future, I can define my own POJO called ProductData that will hold the required contents of the file. I can then create a concrete class called ProductDataFlatFileParser that implements the Parser interface and have the parse method populate the ProductData POJO for me after parsing the file.


Does this design make sense? Are there any obvious flaws in this design? As the design stands, I am allowing the concrete classes to define the algorithm to parse a file and letting the concrete class decide where to populate the data. The design seems to be more dependent on the domain objects rather than the file formats. Is this a bad thing? Any inputs on how I can improve my design will be highly appreciated.

Answered by ananya Pawar

Your design is not the best option. By your design, the only way to use it:


ProductDataXMLTYPE parser = new ProductDataXmlParser().parse(input); 
ProductDataTextTYPE parser = new ProductDataTextParser().parse(input);
We can't see too much benefit from the above example. We can't do things like this:
Parser parser = getParser(string parserName);
parser.parse();
You can consider the following two options before seek the generic:
1, Same output after parse
No matter where the data source is from, the product data will be the same format before you save it to the database. It's the contract between the client and your dump service. So I assume you have the same ProductData as output. You can simply define a interface:
public interface Parser {
    public ProductData parse(String inputFile);
}
Moreover you define ProductData as an interface if you want it more flexible.
If you don't want the Parser file to be mixed with the data. You can split it to two interface:
public interface Parser {
     public void parse(String inputFile);
}
public interface Data {
    public ProductData getData();
}
And your parser will look like this:
public class XMLParser implements Parser, Data {}
public class TextParser implements Parser, Data {}
2, different output after parse
If the ProductData is not similar and you do want to reuse the Parser interface. You can do it this way:
public interface Parser {
   public void parse(String inputFile);
}
class XMLParse implements {
      @Override
      public void parse(String inputFile);
      ProductDataXML getProductData();
}
class TextParse implements {
      @Override
      public void parse(String inputFile);
      ProductDataText getProductData();
}

Your Answer

Interviews

Parent Categories