Überlegung zu generisches Parsermodell

continue

Aktives Mitglied
Hallo,

Angenommen ich habe sagen wir mal zwei verschiedene Parser klassen P1 und P2 die halt irgendwas parsen.
Um ein einheitliches Interface für die Parser zu haben, implementieren diese ein gemeinsames Interface PInterface.
Jeder der zwei Parser versteht ein bestimmtes format welches er in der im Interface definierten Methode bekommt.

Was ist nun der best-practice weg um zu entscheiden welcher parser wirklich verwendet wird..

An irgendeiner Stelle habe ich ja dann diesen Code:

PInterface parser = new P1();
oder eben
PInterface parser = new P2();

Natürlich könnte ich das zu parsende Format nun mit "instanceof" überprüfen und dann eben entweder P1 oder halt P2 instanzieren... das möchte ich aber nicht.

wie kann ich sicherstellen dass der richtige parser verwendet wird?


Ein anderer Ansatz wäre dass ich es mit einer generischen Klasse realisiere:
class ParserApplication<der jeweilige parser> { }

dann hätte ich sowieso zugriff zum jeweiligen richtigen parser.
 
Zuletzt bearbeitet:

gustav

Aktives Mitglied
Sorry, so richtig kann ich Dir nicht folgen! Wenn du das "Format" übergibts mußt Du ja schon irgendwie wissen um was es sich handelt oder?

Was verstehst Du unter Parser? Normalerweise ist da meist noch ein Lexer mit dabei der die Eingabe in Token zerlegt die dann vom Parser verarbeitet werden. Kannst Du hier nicht ansetzen und das Format erkennen?
 

Marco13

Top Contributor
So ganz verstehe ich es auch noch nicht, aber ...

Was ist nun der best-practice weg um zu entscheiden welcher parser wirklich verwendet wird..

... genau DAS sollte ja NICHT notwendig sein. Sonst sind das ja nicht beides (durch das Interface als solche festgelegt) "gleichartige" Parser. Beschreib' ggf. mal genauer, was du meinst.

(Es gibt so einen leicht... grenzwertigen Übergang zwischen sauberem OOP mit Interfaces und "ancient school" C-Stil... Entweder es sind Interfaces, oder es wird mit instanceof gearbeitet - oder die Mogelpackung: Im Interface steht eine Methode a la "getType" ... :autsch: )
 

mvitz

Top Contributor
Idr. wird so etwas durch eine Factory gelöst. Jedoch braucht auch diese irgendeine Information, welchen Parsertyp sie nun erzeugen soll.
 

continue

Aktives Mitglied
Ok, ich habe mich irgendwie äußerst ungünstig ausgedrückt.
Also es geht um genau folgendes.

Ich habe mehrere Java Beans welche verschiedene Attribute haben. Diese Javabeans sollen mittels gewisse Klassen in eine andere form gebracht werden. Zum Beispiel eine BeanA soll mittels einer Klasse Formater4BeanA einen Output erzeugen. Für eine andere Bean gibt es wieder eine andere Klasse.

Diese Klassen die für jeweils eine Bean einen formatierten output erzeugen sollen möglichst gleich verwendbar sein und es soll auch möglich sein einen neuen "Formater" für eine neue Bean hinzuzufügen. Deshalb implementieren diese Formater mal alle ein Interface IFormater.

Im Hauptprogramm, kommt jetzt eine Bean daher und es soll "automatisch" der richtige Formater für diese Bean (also bei BeanA der FormaterA) verwendet werden.

Das könnte man jetzt so machen:

Java:
IFormater formater;
if (Bean instanceof BeanA) {
formater = new BeanAFormater();
formater.parse(Bean);
}

Das kommt mir aber nicht so sauber vor...
Denn wenn jetzt eine neue Bean und für diese ein neuer Formater hinzugefügt wird muss man hier wieder einen if zweig einfügen usw.

Was ist hier der sauberere Ansatz?

Ich hoffe es ist jetzt ca. klar was ich meine :)

lg
 
Zuletzt bearbeitet:

Landei

Top Contributor
Jeder Formatter könnte eine Methode definieren, die eine Liste von Class-Objekten zurückliefert. In einer Art Registry könnte man damit eine Map<Class<?>, Formatter> aufbauen, die einen passenden Formatter für jedes Objekt heraussucht.

Noch flexibler ist, wenn jeder Formatter eine boolesche Methode accepts definiert, der man ein Objekt übergibt und der Formatter selbst "entscheidet", ob er damit zuruchtkommt. Natürlich sollte es dann nicht zuviele Formatter geben, da man immer eine Liste durchprobieren muss, bis man einen passenden findet.
 
T

Tomate_Salat

Gast
wie wäre es [c]BeanA[/c] einfach eine Methode: [c]getFormatter()[/c] zu geben, welche den für diesen Bean passenden Formatter zurückgibt, oder BeanA einfach selbst IFormatter implementiert?
 

Landei

Top Contributor
Halte ich für eine schlechte Idee, das ist genau falschrum. Das Bean sollte nichts darüber wissen, wie es dargestellt/weiterverarbeitet/verhackfrühstückt wird.
 

continue

Aktives Mitglied
Danke euch für eure Vorschläge. Das hilft mir schon mal weiter.

Eine (gute? / nicht gute?) Idee hätte ich selbst auch noch:

Also die Instanzierung der Formater erfolgt ja in einer eigenen Klasse, nennen wir sie "FormaterComponent". Diese könnte ich doch eigentlich generisch machen, oder?

Java:
class FormaterComponent<T extends IFormater> {
private T formater;
}

damit könnte ich den die FormaterComponent klasse folgends instanzieren:
Java:
FormaterComponent<Formater4BeanA> ff4ba = new FormaterComponent<Formater4BeanA>(BeanA);

Wie gut oder schlecht wäre dieser ansatz nun?
 
T

Tomate_Salat

Gast
@Landei: Ich würde hier auch die getFormatter-Variante nehmen. Diese könnte man dann über einen setter definieren. Macht natürlich nur Sinn, wenn es immer auf die gleiche Art und Weise behandelt werden soll (wovon ich mal ausgegangen bin).
 

Marco13

Top Contributor
...Wie gut oder schlecht wäre dieser ansatz nun?

Mir ist nicht klar inwieweit damit das Problem gelöst werden sollte.
Java:
void doSomething(Bean bean)
{
    // Welches nun?
    FormaterComponent<Formater4BeanB> ff4ba = new FormaterComponent<Formater4BeanA>(bean);
    FormaterComponent<Formater4BeanB> ff4bb = new FormaterComponent<Formater4BeanB>(bean);

Landei hat schon recht: So eine Verdengelung zwischen dem Bean selbst und dem Formatter klingt, als sollte man da vorsichtig sein. (Ja, bei Scala könnte man da - soweit ich das bisher verstanden habe :oops: - Pattern Matching verwenden... ;) )

Man müßte genauer wissen, wer wann und auf Basis welcher Kriterien entscheiden kann, welcher Formatter verwendet werden kann, und welche es überhaupt gibt. Hängt der Formatter NUR von der Klasse ab? Was passiert, wenn es zu einer Bean-Klasse keinen passenden Formatter gibt? ...
 

continue

Aktives Mitglied
Mir ist nicht klar inwieweit damit das Problem gelöst werden sollte.
Java:
void doSomething(Bean bean)
{
    // Welches nun?
    FormaterComponent<Formater4BeanB> ff4ba = new FormaterComponent<Formater4BeanA>(bean);
    FormaterComponent<Formater4BeanB> ff4bb = new FormaterComponent<Formater4BeanB>(bean);

Landei hat schon recht: So eine Verdengelung zwischen dem Bean selbst und dem Formatter klingt, als sollte man da vorsichtig sein. (Ja, bei Scala könnte man da - soweit ich das bisher verstanden habe :oops: - Pattern Matching verwenden... ;) )

Man müßte genauer wissen, wer wann und auf Basis welcher Kriterien entscheiden kann, welcher Formatter verwendet werden kann, und welche es überhaupt gibt. Hängt der Formatter NUR von der Klasse ab? Was passiert, wenn es zu einer Bean-Klasse keinen passenden Formatter gibt? ...


Hallo,
Jede Bean hat genau einen Formater. Es ist sogar ganz genau klar welcher Formater es ist.
Deshalb erscheint mir der Ansatz mit der generischen Komponente irgendwie gut, weil ich hier wenn ich eine neue Bean habe einfach FormaterComponent<IFormater> instanziere. und sonst nirgends was ändern muss...

Java:
FormaterComponent<IFormater> f4ba = new FormaterComponent<IFormater>(new Formater4NewBean());
 
Zuletzt bearbeitet:

gustav

Aktives Mitglied
Na denn ist doch der Ansatz mit der Map ganz gut. Dort trägst du dann zu jeder Bean den Formatter ein.
Den Vorschlag mit dem getter an der Bean halte ich für unsauber. Denn die Bean sollte nicht wissen wer sie manipuliert und wenn sie es wüßte - könnte sie sich ja auch gleich selber formatieren....
 

continue

Aktives Mitglied
Ja ich werde es dann eh entweder mit einer Map machen oder eben mit der generischen Klasse. :)
Atm finde ich beide lösungen irgendwie nett :) herzlichen Dank.

zur Map Idee noch eine Frage:

Was speichere ich da am besten als schlüssel-und Werte paar?
Soll ich hier Strings der Klassennamen speichern? oder class objekte? oder die Objekte selbst?
 


Schreibe deine Antwort... und nutze den </> Button, wenn du Code posten möchtest...

Ähnliche Java Themen

Neue Themen


Oben