Der Aufbau meiner Konfigurationen ist schlecht



  • Prof84 schrieb:

    Um Baumstrukturen vernünftig abzufragen, siehe Dir doch mal das Kompositum (Composite) Pattern der GoF an
    http://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)

    Was meinst du denn damit?

    Prof84 schrieb:

    Um endlose Routinen zu vermeiden, um die Baumstrukturen zu parsen, nutze den das DOM Model (Parser)
    http://en.wikipedia.org/wiki/Document_Object_Model

    und den Standard XPath:
    http://www2.informatik.hu-berlin.de/~obecker/obqo/w3c-trans/xpath-de/

    Was spricht hier gegen SAX? Wenn ich das richtig verstanden habe wird das Dokument einmal durchlaufen, die Pipeline aufgebaut und fertig.



  • finix schrieb:

    endline schrieb:

    Hallo Welt,

    ich programmiere ein Programm, dessen Verhalten von Konfigurationsdateien gesteuert wird. Die Konfigurationen sind im XML-Format beschrieben, aber mit dem Aufbau bin ich ueberhaupt nicht zufrieden.

    Hallo endline,

    ist XML àls Format vorgegeben?

    Nein. Ich kann benutzen, was ich will...
    Ich hab XML genommen, weil es einfach zu parsen ist, mit gegebenen Libraries.

    Was spricht hier gegen SAX?

    Ich schau mir das mal an.



  • Gibt es eine feste Anzahl von Modulen oder ist auch das flexibel? Da ein Modul und dessen Inhalt ja maßgeblich von dessen Typ bestimmt zu sein scheint, könntest du doch z.B. statt "modul" andere Tag-Namen verwenden? In etwa so?:

    <pipeline_modules>
    
        <FlatFileSource datasource=true>  <!-- "datasource=true" gibt an, dass es die Datenquelle ist -->
            <!-- Wenn hier ein Pfad zu einer Datei steht, wird  
            das Modul mit diesem Pfad initialisiert, wenn der
            Knoten leer bleibt, wird der Pfad in der GUI angegeben -->
            <data_source></data_source>
        </FlatFileSource>
    
        <CSVParser>
            <delimiter character=';'/>
            <delimiter hexadezimal='09'/>
        </CSVParser>
    
        <TextFilter>
            <content>blank</content>
            <content>12345</content>
            <line>1</line> <!-- das ist nicht immer erforderlich -->
        </TextFilter>
    
        <moduleXY>
            <!-- andere -->
        </moduleXY>
    
        <SqlServerTableSource> <!-- Datenquelle -->
            <connection_string>ConnectionString</connection_string>
            <data_source>EinTabellenName</data_source>
        </module>
    
    </pipeline_modules>
    

    Finde ich persönlich jedenfalls übersichtlicher, und dann halt noch genau spezifizieren, welche Inhalte drin sein müssen/dürfen.



  • endline schrieb:

    finix schrieb:

    ist XML àls Format vorgegeben?

    Nein. Ich kann benutzen, was ich will...
    Ich hab XML genommen, weil es einfach zu parsen ist, mit gegebenen Libraries.

    Dann wären vielleicht YAML, JSON oder gar - 😮 - SEXPs eine Alternative.

    Was natürlich nicht automatisch das Problem deiner "switch- und if-Orgie"* löst.

    endline schrieb:

    Was spricht hier gegen SAX?

    Ich schau mir das mal an.

    SAX ist kein Format, sondern einfach eine andere Variante XML-Dateien einzulesen.

    * Wie sieht dein Parser denn derzeit aus? Das sieht doch aus als ließe es sich perfekt modularisieren.



  • finix schrieb:

    Dann wären vielleicht YAML JSON SEXPs eine Alternative.

    oder das hier: http://en.wikipedia.org/wiki/Type-length-value
    ist eben nur kein textformat.
    🙂



  • finix schrieb:

    Was meinst du denn damit?

    Wenn er ein variables Konfigurationsschema hat, muss er naturlich in seiner Applikation ein variables Parse- und Build-Model bauen. So kann man eine Ausrollung des Baumes verhindern, was dann zu unzähligen Fallunterscheidungen führen würde.

    finix schrieb:

    Was spricht hier gegen SAX? Wenn ich das richtig verstanden habe wird das Dokument einmal durchlaufen, die Pipeline aufgebaut und fertig.

    Das Problem bei SAX ist, dass er das Parse- und Build-Modell gleichzeitig umsetzen muss während er die Konfig durchläuft. Das führt im Regelfall zur Redundanz und fordert ein sauberes 'Design by Contract' im System Engineering. D.h.: Wenn sich Abhängigkeiten zwischen Modulen ergeben kannst Du jene mit SAX nicht nutzen ohne das Parsen wieder von Vorne zu beginnen. Deshalb meine Empfehlung zu DOM.



  • Also wenn ich dich richtig verstanden hab, dann hat jedes module nen type und dann unterschiedliche parameter.
    Dann würde ich es so machen.

    <pipeline_modules>
    	<module> <!-- Datenquelle -->
    		<type>SqlServerTableSource</type>
            <params>
    		     <connection_string>ConnectionString</connection_string>
    		     <data_source>EinTabellenName</data_source> 
            </params>
    	</module>
    	...
    </pipeline_modules>
    

    Dann würde ich type und die params an ne Factory übergeben. Die Factory hat ne Map mit key = type und value = Utilityklasse die das Modul erstellt. Die params übergibst du dann an die Utilityklasse und die erstellt damit das entsprechende Modul.



  • Das mit der switch/if-Orgie lässt sich vielleicht lösen, indem du eine Klasse erstellst, die die Konfiguration einliest (egal ob jetzt XML oder etwas anderes), und dann die Werte nicht über irgendwelche if-Anweisungen in Variablen ablegst, sondern die eingelesen Werte in einer Map abspeicherst.

    Nehmen wir an du hast eine einfache .ini-Datei mit folgendem Eintrag:

    farbe = rot
    

    Dann liest du das ein, und speicherst das Paar ("farbe" , "rot") ab.

    Über die Klasse bietest du dann eine Funktion an, mit der du den Wert eines bestimmten Konfigurationseintrages erhälst.
    Also so etwas:

    std::string getValue(std::string conf);
    

    Dann greift der Rest deines Codes halt nicht auf irgendwelche Variablen zu, sondern auf die Konfigurationsklasse.

    Könnte so funktionieren.

    Viele Grüße

    EDIT:
    Vielleicht war das sowas Ähnliches, wie mein Vorposter mit seiner Factory-Lösung meinte...



  • Prof84 schrieb:

    finix schrieb:

    Was meinst du denn damit?

    Wenn er ein variables Konfigurationsschema hat, muss er naturlich in seiner Applikation ein variables Parse- und Build-Model bauen. So kann man eine Ausrollung des Baumes verhindern, was dann zu unzähligen Fallunterscheidungen führen würde.

    Ich weiß dass du gerne mit Fachwörtern und Buzzwörtern und Phrasen hantierst, aber könntest du dich einen Augenblick zügeln?

    Deine Ausführung verrät mir kein bisschen worin du das Problem eines "variables Konfigurationsschemas" siehst, was du überhaupt mit "Ausrollung des Baumes" meinst bzw. wo die "unzähligen Fallunterscheidungen" herkommen oder wie das Composite Pattern hier Abhilfe schafft.

    Prof84 schrieb:

    finix schrieb:

    Was spricht hier gegen SAX? Wenn ich das richtig verstanden habe wird das Dokument einmal durchlaufen, die Pipeline aufgebaut und fertig.

    Das Problem bei SAX ist, dass er das Parse- und Build-Modell gleichzeitig umsetzen muss während er die Konfig durchläuft. Das führt im Regelfall zur Redundanz und fordert ein sauberes 'Design by Contract' im System Engineering. D.h.: Wenn sich Abhängigkeiten zwischen Modulen ergeben kannst Du jene mit SAX nicht nutzen ohne das Parsen wieder von Vorne zu beginnen. Deshalb meine Empfehlung zu DOM.

    Inwieweit ist ein Single Pass Modell ein Problem (sicher nicht wegen "Abhängigkeiten zwischen Modulen")? Wegen der SAX-spezifischen Redundanz (was meinst du damit, und wo kommt die her)?



  • Benutzernamen ein. schrieb:

    Also wenn ich dich richtig verstanden hab, dann hat jedes module nen type und dann unterschiedliche parameter.
    Dann würde ich es so machen.

    <pipeline_modules>
    	<module> <!-- Datenquelle -->
    		<type>SqlServerTableSource</type>
            <params>
    		     <connection_string>ConnectionString</connection_string>
    		     <data_source>EinTabellenName</data_source> 
            </params>
    	</module>
    	...
    </pipeline_modules>
    

    Dann würde ich type und die params an ne Factory übergeben. Die Factory hat ne Map mit key = type und value = Utilityklasse die das Modul erstellt. Die params übergibst du dann an die Utilityklasse und die erstellt damit das entsprechende Modul.

    Die Idee gefällt mir gut. Es gab noch andere hilfreiche Tips, ich hab schon eine Vorstellung davon, wie ich das kombiniere und wie das Endprodukt aussieht 🙂

    Danke an alle!


Anmelden zum Antworten