mardi 28 mars 2017

Java Command Pattern prepopulate list of Invoker class

I have number of classes that parses String. These Strings are sent by LAS (Laboratory Automation System) machines after performing sample's tests and then parser classes are responsible to parse them and extract results from String.

As every machine sends String in different formats, so can't have single and generic String parser. The class responsible to get String from machine is called Controller. Controller knows all the information of machine and is generic. There is only one Controller and multiple parser.

Now the problem is how Controller will know which parser to invoke for data extraction.

I have implemented Command Pattern but according to the example, private List<Order> orderList = new ArrayList<Order>(); this list needs to be populated before invoke() is called out.

So, it sense that I need to create object of all Parser classes and add them in list in order to know which Parser should be invoked.

Here is my code:

Abstract Parser:

public abstract class Parser {

private final String resultString;
private final String machineId;

  protected Parser(final String result, final String machineId){
    resultString = result;
    this.machineId = machineId;
  }

  /**
   * This method's implementation will parse the output string. The method    @see setResultString(String) must be called before parsing. 
   */
  abstract void  Parse();

  protected String getResultString(){
     return this.resultString;
  }

  protected String getMachineId(){
     return this.machineId;
  }
}

Concrete Parser:

1. COBASParser

public class COBASParser extends Parser{

  public COBASParser(final String resultString, final String machineId){
     super(resultString, machineId);
  }

@Override
 void Parse() {
     System.out.println("This is COBAS's Parse() method");
     System.out.println("ResultString:: "+getResultString());
  }

}

2. E170Parser

public class E170Parser extends Parser {

  public E170Parser(final String resultString, final String machineId) {
     super(resultString, machineId);
  }

  @Override
  void Parse() {
     System.out.println("This is E170Parser's Parse() method");
     System.out.println("ResultString:: "+getResultString());
  }
}

Invoker Class:

public class ParserInvoker {

  private static ParserInvoker me;
  private List<Parser> parsersList;

  private ParserInvoker() {
     parsersList = new ArrayList<>();
  }

  public void addParser(Parser parser) {
     parsersList.add(parser);
  }

/**
 * Invokes concrete class parser.
 * @param machineId 
 */
 public void invoke(final String machineId) {
      for (Parser p : parsersList) {
         if (p.getMachineId().equals(machineId)) {
             p.Parse();
         }
      }
 }
 public static synchronized ParserInvoker getInvoker() {
     if (me == null) {
         me = new ParserInvoker();
      }
      return me;
 }
}

What should I do? Should I adopt any other pattern (Abstract Factory Pattern) or I haven't implemented the Pattern correct?

Here is my Controller

class LASController{

   void OnDataRecieve(String resultString, String machineId){
     // Call Parser here
   }

}

Aucun commentaire:

Enregistrer un commentaire