Designfrage (Objektorientierung)



  • Hallo,

    ich hätte eine Designfrage und zwar zur Auftrennung von Komponenten.
    Folgendes Szenario:

    1. Ich lese Daten aus dem ComPort -> ComPort Klasse
    2. Ich parse diese Daten zur weiterverarbeitung -> Parser Klasse
    3. Ich verarbeite diese Daten und führe mehrere Berechnungen mit ihnen durch -> Verarbeitungs Klasse

    die erste Frage wäre jetzt, soll ich das Parsing noch mit in die Verarbeitungs Klasse packen? Das Parsing ist nicht übermäßig komplex, werden wohl so 200-300 Zeilen Code sein.

    4. Ich möchte die Daten in 3-4 Diagrammen auf dem Bildschirm darstellen

    Hier jetzt die große Frage, wie kapsele ich das am besten? Ich habe zum einen meine GUI welche durch eine Control Klasse mit z.B. der Verarbeitungs Klasse verbunden ist. Für die GUI verwende ich wxWidgets. Sollte ich nun eine weitere Klasse in der Art von "Darstellung" machen der ich die verarbeiteten Daten übergebe und die sie dann auf den Bildschirm zeichnet? Wäre ja eigentlich nicht ganz im Sinne von OOP da ich ja keine Datenhaltung dabei hätte, oder halt nur in grafischer Form. Allerdings kommt mir die Verarbeitungs Klasse so überladen vor wenn sie eine Million Dinge kann.

    Naja, danke schonmal & Gruss,

    Max

    #edit: Noch eine Frage am Rande:

    Ich versuche meine Programm meist so zu designen:

    GUI |-----| Control Klasse |-----| Datenhaltung und Verarbeitung
    wobei Datenhaltung und Verarbeitung nicht aufgetrennt sind sondern möglichst Objektorientiert in einzelnen Klassen zusammengepackt werden.

    Zum einen, ist das so sinnvoll? Wenn nein, wie könnte man das sinnvoller gestalten?

    Zum anderen, sehe ich es richtig dass bei einer 3-Schicht-Architektur Datenhaltung und Verarbeitung aufgeteilt werden womit ich ja wieder eine prozedurale "Strukturierung" (nennt man das so?!) hätte. Lassen sich 3-Schicht-Architektur und OOP überhaupt vereinen?



  • Sieht sinnvoll aus, nennt sich Model View Controller, kurz MVC. Das Model repraesentiert die Daten im Programm und die ganzen Operationen auf den Daten. Dazu gehoert aber nicht z.B. Speichern und Laden (wenn man strikt ist). Die Parserklasse benutzt nur das Model und die I/O (ComPortklasse) um es mit sinnvollen Daten zu fuellen, angezeigt wird es durch deine View (jeder Diagrammtyp ist halt ne andere View auf deine Daten), gesteuert wird das ganze durch die Controller. Controller koennen auch GUI-Elemente wie Menues etc. sein. Mehr dazu hier: http://de.wikipedia.org/wiki/Model_View_Controller



  • Tag,

    schonmal danke für die Tips, das MVC Design war mir bisher nicht bekannt (zumindest nicht unter dem Namen ;)).
    Ich habe hier mal ein (beschnittenes) Klassendiagramm gebastelt:

    http://img90.imageshack.us/img90/2482/designm.jpg

    Die Kommunikation zwischen Daten und Verarbeitungs Klassen erfolgt ausschließlich über die Control Klasse. Der Design Ansatz für die Grafischen Funktionen ist bisher die Idee den Funktionen einen Zeiger auf ein Image zu übergeben auf welches gezeichnet wird, allerdings bin ich damit irgendwie noch nicht so ganz zufrieden, gibt es da etwas besseres?
    Zudem stellt sich mir nun die Frage wo ich das Laden und Speichern der Daten die in der "Dataset" Klasse liegen implementieren soll, denn ich hatte vor sie in ebendiese Klasse zu packen.

    Dazu gehoert aber nicht z.B. Speichern und Laden (wenn man strikt ist).

    Wo also dann? Nochmals eine extra Klasse die nichts anderes macht als meine Daten aus der Datenbank zu lesen und wieder zu schreiben?

    Gruss,

    Max



  • MVC solltest du nicht als Dogma ansehen. Dein Model kann durchaus sowas wie load() und save() anbieten, wenn du willst. Die Datenbankanbindung wurde ich trotzdem kapseln. Du schreibst dir ein Interface mit den noetigsten Funktionen fuer die Serialisierung (erstmal Datenbank unabhaengig) und die Implementation dieses Interfaces regelt dann das mit der Datenbank. Der Vorteil: Willst du kein Datenbankzugriff sondern irgendwann einfach nur auf die Platte schreiben, dann sieht die Implementation des Interfaces halt anders aus, brauchst aber den Rest des Codes nicht anpassen.

    Z.B.: DatabankSerialize erbt von ISerialize und implementiert load und save, die als Parameter dein Model bekommen. Nebenbei muss DatabankSerialize noch Methoden anbieten, um Verbindung, Datenbanktype etc. setzen zu koennen. Diese kann der Controller dann benutzen. Der Instanziiert einfach DatabankSerialize, setzt die Datenbankinformationen und ruft save( Model ) auf. Willst du auf Platte schreiben einfach ToFileSerialize implementieren und save( Model ) aufrufen.

    Es hilft zu experimentieren (auch im Falle der View), denn Moeglichkeiten gibt es viele. Auch hilft es, andere Programmiersprachen anzusehen. In C# gibt es da schon vorgefertigte Designs in der Sprache, die man auch fuer C++ uebernehmen kann.



  • Tag,

    hätte da nochmal eine Frage zu deinem Tipp mit den Extra Klassen für die Serialisierung. Habe hier mal etwas Code geschrieben der für mein Projekt passen könnte:

    class Serialization
    {
        protected:
        std::map<std::string> data;
    
        public:
        virtual std::vector<Node> load(std::string path)=0;
        virtual void save(const sdt::vector<Node> &nodes)=0;
        void serializeData(const std::vector<Node> &nodes);
    };
    
    class SQLiteSerialization : public Serialization
    {
        public:
        std::vector<Node> load(std::string path);
        void save(const sdt::vector<Node> &nodes);
    };
    

    Hast du das so gemeint?

    #edit: In der Dataset Klasse würde ich das etwa so implementieren:

    class Dataset
    {
        private:
        Serialization *serialization;
    
        public:
        Dataset()
        {
            serialization = new SQLiteSerialization;
        }
    }
    

    Dann müsste ich immer nur eine Zeile leicht ändern.



  • In etwa, ich persoenlich wuerde aber die SQLiteSerialization im Controller definieren. Ganz einfach: Was machst du, wenn du einfach nur in eine Datei schreiben moechtest (und die Moeglichkeit anbietest in eine Datenbank zuschreiben)? Neuen Controller hinzufuegen ... das Model wird nicht einmal angefasst. Aber wie gesagt, experimentieren ... Auch weiss ich wenig ueber die Gesamtarchitektur und das eigentliche Programm, kann dir nur Moeglichkeiten aufzeigen. Was toll ist, ist (meist) Ansichtssache. Dein Vorschlag ist auch ok.



  • Ok, du hast mir auf jeden Fall sehr geholfen mit deinen Tips, Danke vielmals ;).


Log in to reply