2017-07-27 2 views
0

Ich habe meine Eingabedatei in allen XML/JSON/CSV/EXCEL-Formaten.am besten geeignete Design-Muster zu wählen Parser basierend auf Eingabedatei

Ich habe separate Parser für alle geschrieben. aber ich möchte meine Analyse zur Laufzeit auswählen.

Welches Designmuster wird am besten geeignet sein?

Ich habe realisiert, wie

if(file.endsWith(".csv")) 
return CSVParser(); 
if(file.endsWith(".json")) 
return JSONParser(); 
if(file.endsWith(".xml")) 
return XMLParser(); 
else 
return EXCELParser(); 

Vorschlag/Richtlinien bitte.

+0

Sie möchten vielleicht die Erweiterung zuerst, d. H. Text nach der letzten Periode, in Kleinbuchstaben konvertieren, dann verwenden Sie eine Zeichenfolge 'switch' Anweisung, aber ansonsten scheint es ok für mich. – Andreas

Antwort

-1

Zunächst einmal alle Parser implementiert die gleiche Schnittstelle:

public class CSVParser implements Parser {} 
public class JSONParser implements Parser {} 
public class XMLParser implements Parser {} 
public class EXCELParser implements Parser {} 

Dann werden zwei Lösungen für die Referenz:

1.Get Parsers in einer Methode:

public Parser getParser(String file){ 
    if(file.endsWith(".csv")) 
     return CSVParser(); 
    if(file.endsWith(".json")) 
     return JSONParser(); 
    if(file.endsWith(".xml")) 
     return XMLParser(); 
    else 
     return EXCELParser(); 
} 

2. Verwendung enum:

public class ParserEnum { 
    CSVParser("csv", new CSVParser()), 
    JSONParser("json", new JSONParser()), 
    XMLParser("xml", new XMLParser()), 
    EXCELParser("excel", new EXCELParser); 

    private String type; 
    private Parser parser; 

    ParserEnum(String type, Parser parser) { 
     this.type = type; 
     this.parser = parser; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public Parser getParser() { 
     return parser; 
    } 

    public void setParser(Parser parser) { 
     this.parser = parser; 
    } 
} 
erhalten

dann Parser von Aufzählungstyp:

public Parser getParser(String file){ 
    if(file.endsWith(".csv")) 
     return ParserEnum.CSVParser.getParser; 
    // ... 
} 
+1

Warum glauben Sie, dass die Parser nicht bereits eine gemeinsame Schnittstelle implementieren? Der Fragecode hat vier 'return new XxxParser()' -Anweisungen. Wenn der Rückgabetyp nicht 'Object' ist, wäre es eine Schnittstelle oder eine gemeinsame Basisklasse.Ihre Antwort fügt nichts von Wert hinzu, da das Enum immer genau die gleiche Art von mehreren if-Anweisungen benötigt. – Andreas

-1

Sie, welche Art von Parser pattern..Let Unterklasse Fabrikentwurf entscheiden können instanziiert werden basierend auf input..also Kunden von Parser muss nicht wissen, welche Art von Parser, indem er erklärt eine gemeinsame Schnittstelle o abstrakte class..for Clients instanziiert wird, wird es so einfach wie

Parser parser=ParserFactory.getParser(String file);

parser.parse(file) sein;

+0

"Lassen Unterklassen entscheiden" impliziert Factory-Methode, aber dieses Muster erfordert einen polymorphen Aufruf (und "getParser" ist nicht polymorph). Sie verwenden eine [einfache Fabrik mit einer statischen Methode] (https://Stackoverflow.com/a/20859513/1168342), die ein anderes Muster ist. – Fuhrmanator

+0

@Fuhrmanator Ich meinte das gleiche .. die Flexibilität der Wahl zwischen einfachen Fabrik oder Fabrik Methode ist bis Benutzer ich glaube .. Danke für die Abstimmung aber :) –

-1

Da die Anzahl der Parser endlich ist und dieselben Initialisierungsparameter akzeptiert, passt das Prototypmuster am besten wie folgt. Hinweis: Prototype verwendet das Klonen und erstellt nicht jedes Mal neue Objekte. Ich glaube, wir benötigen nicht geteilte Instanzen.

public class ParserRepository { 
    private Map<String,BaseParser> prototypes = new HashMap<>(); 
    public ParserRepository(){ 
     prototypes.put(".csv",new CSVParser()); 
     prototypes.put(".json",new JSONParser()); 
     prototypes.put(".xml",new XMLParser()); 
    } 

    public BaseParser getParser(String extension) { 
     BaseParser parser = null;; 
     try { 
      parser = (BaseParser) prototypes.get(extension).clone(); 
     } catch (CloneNotSupportedException e) { 
      // Handle exception here 
      e.printStackTrace(); 
     } 
     return parser; 
    } 
} 

Bei neuen Prototyp muss das Repository hinzugefügt werden können dynamisch, geeignete Methoden für die ParserRepository Klasse ausgesetzt werden.

+0

Die Komplexität des Prototyps ist das Problem der "Vermeidung der inhärenten Kosten von Erstellen eines neuen Objekts auf die übliche Weise (z. B. mit dem Schlüsselwort "new"), wenn es für eine bestimmte Anwendung unerschwinglich teuer ist. " Es scheint, dass ein Teil des Musters im OP-Beitrag nicht gilt. – Fuhrmanator

0

Simple factory würde Ihr Problem lösen. Es ist kein true Design-Muster (nicht in der ursprünglichen GoF-Reihe von Mustern), sondern eher eine Möglichkeit, eine Lösung zu kodieren (aka idiom). Es unterscheidet sich von Factory Method und Abstract Factory (siehe den Link oben, um den Unterschied zu verstehen).

enter image description here

Sie müssen keine statische Methode verwenden. Aber es ist praktisch, es in die Oberklasse zu bringen.

Verwandte Themen