Design-Problem Formel-Parser

Landei

Top Contributor
Ich habe einen Formel-Parser, der relativ unabhängig arbeitet. Er soll jedoch auch Konstanten, die von "außen" geliefert werden, verarbeiten können. Genau diese Verbindung macht Probleme.

Ich benutze eine Klasse ConstToken, die eine Unterklasse von ValueToken ist (die anderen Unterklassen sind Zahlen und Variablen):

Java:
public abstract class ValueToken<T> implements Token<T> {
    public abstract T get();
}

public class ConstToken<T> extends ValueToken<T> implements Token<T> {

    private final String name;
    private final ConstProvider<T> provider;
    
    public ConstToken(String name, ConstProvider<T> provider) {
        this.name = name;
        this.provider = provider;
    }
    
    @Override
    public T get() {
        return provider.get(name);
    }
    ...
}

Die Verbindung mit der "Umgebung", die die Konstanten-Werte liefert, geschieht über das Interface ConstProvider:
Java:
public interface ConstProvider<T> {
   public T get(String name);
   public boolean exists(String name);
}

Das alles wäre in einer "statischen" Umgebung kein Problem. Ich habe jedoch in Probleme, wenn ich alles initialisiere (weil dann eine Formel über ConstProvider auf eine andere Formel verweisen kann, die noch gar nicht konstruiert wurde), und wenn eine Formel kopiert wird (weil sich dann die Bedeutung dessen, was referenziert wird, teilweise ändert - etwa so, wie wenn man ein Programm verschiebt, das relative Pfadnamen benutzt).

Wie kann ConstToken zu seinen Werten gelangen, ohne sich über ConstProvider zu früh und zu stark an die Umgebung zu koppeln?

Ich habe das dumme Gefühl, dass ich irgend etwas Offensichtliches übersehe. Es doch muss irgendeine Möglichkeit zu einer Art Lazy Loading mit gleichzeitiger Inversion of Control geben...
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Hm - für konkretere Tipps müßte ich da jetzt auch erst genauer überlegen (und bezweifle auch, dass ich auf abstraktere oder elegantere Ideen kommen würde, als du). Aber mir stellt sich die Frage, ob das überhaupt immer in der allgemeinsten Form gelöst werden kann: Man könnte da doch etwas bauen, wo zwei ConstToken gegenseitig das sind, was von ihrem ConstProvider zurückgeliefert werden soll (kurz: Eine zirkuläre Anhängigkeit) ....?!
 

Landei

Top Contributor
Eine unschöne Lösung wäre, den ConstProvider erst "im letzten Moment" mitzugeben (und alle Tests auf Gültigkeit extern zu erledigen):
Java:
public class ConstToken<T> extends ValueToken<T> implements Token<T> {
 
    private final String name;
  
    public ConstToken(String name) {
        this.name = name;
    }
    
    public T get(ConstProvider<T> provider) {
        return provider.get(name);
    }
    ...
}

Damit könnte man allerdings nicht mehr ValueToken als Oberklasse verwenden (was bisher die Implementierung des Parsers sehr vereinfacht hat). Oder ich ändere die Signatur von get auch in ValueToken, und muss dann für Zahlen und Variablen einen völlig überflüssigen ConstProvider mitgeben.

Da muss ich nochmal drüber meditieren, kann doch nicht so schwer sein...
 

Marco13

Top Contributor
Hmnee, ich hätte schon vermutet, dass das den Grundgedanken des ValueToken ziemlich kaputt machen würde. Ich weiß nicht, wie du die Variablen und deren Belegung jetzt gelöst hast, oder wie das Konstruieren der Formel im Moment genau implementiert ist, oder wie die Auswertung genau abläuft (und wie viel oder wenig sie mit der Konstruktion zusammenhängt - u.U. könnte ja JEDES Token eine get-Methode haben, die bei "OperatorTokens" dann eben die Auswertung macht). Aber erstmal könnte man denken, dass während des Konstruierens egal ist, worauf der Const-Provider verweist, weil sein Inhalt ja eigentlich erst bei der Auswertung abgefragt werden muss.... also sowas wie
Code:
ConstProvider cp0 = new ConstProvider(null);
ValueToken v0 = new ValueToken(constProviderA);
könnte/sollte ja gehen, und erst bei
Code:
Object o = v0.get();
würde dann aus dem ConstProvider eine NullPointerException geflogen kommen. Wenn man aber
Code:
ConstProvider cp0 = new ConstProvider(null);
ValueToken v0 = new ValueToken(constProviderA);

[b]cp0.setConstValue(new Object());[/b]

Object o = v0.get();
macht, würde es passen. (Ich gehe davon aus, dass dir das klar ist - es geht nur um die Gründe, warum das eben NICHT funktioniert ... ?)
 

Landei

Top Contributor
Wie kann man sich denn solche "Konstanten von außen" vorstellen? Was ist denn das Alles?

Glaspreise in einer Preisliste. Nun gibt es sehr viele davon, und der Markt ist sehr dynamisch, deshalb lassen sich Formeln hinterlegen. In den Formeln kann man auf Preise von anderen Produkten oder Eigenschaften des aktuellen Produkts (Dicke, Anzahl Folien u.s.w.) verweisen. Formeln können auch kopiert, nicht nur zwischen Produkten, sondern auch zwischen verschiedenen Kunden u.s.w.

Damit hat man ähnliche Probleme wie in Excel: Wie vermeidet man zyklische Abhängigkeiten, was passiert mit den Referenzen beim Kopieren u.s.w.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Ganz grob und diffus rumgesponnen: Vielleicht wäre irgendeine Art "globaler validation" zu einem bestimmten Zeitpunkt möglich. Für ein Kopieren müßte der ConstProvider entweder eine formal beschreibende, "übertragbare" Identifikation seiner Quelle enthalten, was schon schwierig bis unmöglich sein kann - und ich gehe davon aus, dass es, obwohl die Values ja "Const" sind, nicht reicht, die einmal abzuholen und zu speichern, sobald die Formel, die den ConstProvider enthält, verschoben oder kopiert wird (in diesem Fall könnte man dem ConstToken ja auch direkt den Wert übergeben...)
 

Landei

Top Contributor
Ich gehe davon aus, dass dir das klar ist - es geht nur um die Gründe, warum das eben NICHT funktioniert ... ?

Im Prinzip mache ich das jetzt so, aber das Problem ist, dass die Zuweisung eines ConstProviders im Konstruktor zu "statisch" ist. Wenn ich z.B. eine Formel (also eine Liste von Tokens) auch für einen anderen Preis verwenden will, brauche ich sie nicht zu kopieren, weil alle Tokens immutable sind - außer wenn ich ConstTokens verwende, die ja dann einen anderen ConstProvider benötigen.

Ich denke, ich muss wirklich in den sauren Apfel beißen, und den Provider erst beim get() mitgeben. ConstToken darf einfach nicht veränderlich sein, das ist das eigentliche Grundproblem, und das ist mir jetzt erst richtig deutlich geworden. Jeder Trick, irgendwie einen Provider dynamisch in ein ConstToken hineinzumogeln (was meine ursprüngliche Idee war), würde mir spätestens beim Kopieren wieder böse auf die Füße fallen.

Danke an alle, ich probiere es so.

[Edit]

Ich sehe gerade Marco's Beitrag. Es würde auf jeden Fall murksig, und ist sehr wahrscheinlich den Aufwand nicht wert. Also kommen wir zur gleichen Schlussfolgerung.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Ich denke, ich muss wirklich in den sauren Apfel beißen, und den Provider erst beim get() mitgeben.
Das hängt ein bißchen mit der Frage zusammen, die ich oben gestellt hatte: Wie werden denn Variablenbelegungen im Moment gelöst? Gibt es Mechanismen, um dieSELBE Formel mit zwei verschiedenen Variablenbelegungen auszuwerten? Worauf das stark vereinfacht rausläuft: In gewisser Hinsicht(!) könnte man das mit dem ConstProvider ja vielleicht "als eine spezielle Form von Variablenbelegung" auffassen... :reflect:
 

Landei

Top Contributor
Die "Variablen" sind aus Sicht der Formel Konstanten (können und sollen innerhalb der Formel nicht geändert werden). Allerdings können sie sich zwischen zwei Berechnungen ändern, oder eine Formel kann unverändert kopiert werden, wodurch einige Konstanten (nämlich die produktabhängigen Parameter) auch einen anderen Wert annehmen.

Ich denke, ich bin auf dem richtigen Weg, wenn ich die Formel völlig unabhängig vom Rest des Programms mache, und Sachen wie Validierung oder Wertebelegung dem restlichen Programm überlasse. Insbesondere die Konsequenz, dass dadurch Formeln als unveränderliche Objekte implementiert werden können, halte ich für wichtig.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Vielleicht hatte ich das etwas unklar formuliert: Es muss ja irgendeine "Entität" geben, die die Variablenbelegung übernimmt. Die (vereinfacht gesagt) irgendwo den String "fensterDickeInMillimetern" auf den Wert "16.8" abbildet - zurückführbar auf eine Methode ValueProvider#getValueFor(String). Wo ist semantisch, für die Formel, und vielleicht nur aus Sicht der Auswertung, der Unterschied zwischen einer Variablen, deren Wert durch die getValueFor(String)-Methode definiert wird, und und einer Konstanten, d.h. "unveränderlichen Variablen", deren Wert durch eine Methode (Const)ValueProvider#getValueFor(String) definiert wird?
Aber vermutlich habe ich einfach ein viel zu wenig klares Bild (und auch zu wenig theoretisch-allgemeine Ahnung von Parsern und Interpretern) als dass ich das wirklich einschätzen könnte. Wenn du eine gute Lösung hast, ist ja alles in Ordnung :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
B Design Problem Allgemeine Java-Themen 8
Torres Design-Problem mit Jakarta Struts Allgemeine Java-Themen 2
J Meinung zum verwendeten Design Pattern Allgemeine Java-Themen 4
S Noch eine Design-Frage zu Setter Allgemeine Java-Themen 6
S ArrayList Design Allgemeine Java-Themen 4
S Interface Design von HookUp oder Callback Methoden für eigenes Framework Allgemeine Java-Themen 9
Kirby.exe Framework für Game Design Allgemeine Java-Themen 8
C WindowBuilder Design funktioniert nicht Allgemeine Java-Themen 0
M Diverse Design-Fragen Allgemeine Java-Themen 6
rentasad Design-Frage - Interfaces, Klassen, statische Methoden Allgemeine Java-Themen 3
M OOP Design Pattern - "extends Observable implements Observer" Allgemeine Java-Themen 0
T OOP Fehler im Design Allgemeine Java-Themen 9
perlenfischer1984 Welches Design Pattern ist geegneit. Allgemeine Java-Themen 7
perlenfischer1984 Hilfe bei Design (Pattern) Allgemeine Java-Themen 5
R Parameter Adapter - Design Allgemeine Java-Themen 1
D Bezüglich Design meines Codes Allgemeine Java-Themen 1
D OOP Design Pattern für GUI - Datenbank Anwendung Allgemeine Java-Themen 1
S Java Design Frage Allgemeine Java-Themen 10
L OOP Klassen-Design (static oder nicht?) Allgemeine Java-Themen 3
P Auf die Anzahl der Joins achten beim WS design Allgemeine Java-Themen 1
M OOP Design Frage Allgemeine Java-Themen 2
J Domain Driven Design - Modellierungsfrage Allgemeine Java-Themen 3
F Welches Design Pattern? Allgemeine Java-Themen 3
H MVC Design Allgemeine Java-Themen 9
J Swing Eigenes Button-design Allgemeine Java-Themen 2
Q Kapselung Allgemeine Design- Frage Allgemeine Java-Themen 8
Z Design um boolsche ausdrücke zu speichern & auszuwerten Allgemeine Java-Themen 3
A Sinnvolles Software Design bei Eigenschaftsänderungen von Objekten Allgemeine Java-Themen 7
C Gutes Code Design (3 Schichten Modell) Allgemeine Java-Themen 19
D Design Stations-Gitter Allgemeine Java-Themen 4
M Public Static importRunning -> Bad Design oder ok ? Allgemeine Java-Themen 5
L Software-Design: Kommunikation mit SerialPort (RXTX) Allgemeine Java-Themen 2
D [Drag&Drop] Design-Pattern-Frage Allgemeine Java-Themen 4
G Design Patterns für Programm Allgemeine Java-Themen 3
I Wie populär ist Design by Contract in Java und was haltet ihr davon? Allgemeine Java-Themen 5
J Aktionen im State-Design-Modell Allgemeine Java-Themen 3
S Design Oberfläche Allgemeine Java-Themen 2
L Design-Frage: Platzierung der Save-Methode Allgemeine Java-Themen 3
G Domain Driven Design Model Allgemeine Java-Themen 14
G konkretes Domain Driven Design Aggregate Allgemeine Java-Themen 2
ruutaiokwu welches design pattern? frage an die oo-experten unter euch... Allgemeine Java-Themen 3
G Accordion Design Pattern Frage Allgemeine Java-Themen 2
hdi Hilfe beim Design (Stichwort OO, Pattern, ...) Allgemeine Java-Themen 11
faulelotte Verständnisproblem Domain Driven Design Allgemeine Java-Themen 3
S Frage zum Design der Datenstruktur Allgemeine Java-Themen 10
D design gesucht - Angabe von zu ersetzenden substrings Allgemeine Java-Themen 2
D Design ohne Getter und Setter Allgemeine Java-Themen 8
D Design: on-the-fly-Parsing + Datenstrukturen Allgemeine Java-Themen 5
N Welches design pattern? Allgemeine Java-Themen 8
D design client server Allgemeine Java-Themen 10
T Design-Frage Allgemeine Java-Themen 14
S XML-Parsing / public-Member-Variablen / Design-Frage Allgemeine Java-Themen 8
S JToolBar Design Allgemeine Java-Themen 3
M Bildersyncronisierung - Design Patterns? Allgemeine Java-Themen 2
T Design - Exception in Thread Allgemeine Java-Themen 3
G Composite, Design Pattern, printTree Allgemeine Java-Themen 42
N Design-Frage: persistent machen per Reflection Allgemeine Java-Themen 3
M Frage zum Design :: allgemein Allgemeine Java-Themen 6
M MVC Design Pattern - Verständniss Fragen Allgemeine Java-Themen 3
U Frage zu DB Design Allgemeine Java-Themen 3
K Design / Implementierung Allgemeine Java-Themen 5
N Checkstyle - Design for Extension Allgemeine Java-Themen 4
F Design Pattern zur Realisierung von Mehrfachvererbung? Allgemeine Java-Themen 8
E Was ist ein gutes Design fuer meine Programm? Allgemeine Java-Themen 3
F Paket und Software Design Fragen. Allgemeine Java-Themen 5
P Apple Design Allgemeine Java-Themen 5
S design frage Allgemeine Java-Themen 10
T Design-Tipp gesucht Allgemeine Java-Themen 2
M Design von Java Klassen Allgemeine Java-Themen 2
G java design von klassen und projekten Allgemeine Java-Themen 6
K Design: Klassen in Pakete aufteilen - Eure Meinung Allgemeine Java-Themen 8
S Programmierstil / design Allgemeine Java-Themen 9
S Exception design Allgemeine Java-Themen 2
m@nu Exception-Design Allgemeine Java-Themen 4
R Design-Frage Allgemeine Java-Themen 9
N Hilfe beim Design Allgemeine Java-Themen 13
D Design Pattern: Singleton Allgemeine Java-Themen 4
A Anwendungs-Design (Plugin-Architektur) Allgemeine Java-Themen 4
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben