Announcement

Collapse
No announcement yet.

Architektur eines simplen Programmes

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Architektur eines simplen Programmes

    Hallo erstmal

    Meine Frage lässt sich denke ich am besten mit einem Beispiel erklären:
    Stellt euch vor ihr wolltet ein Programm machen, das irgendwelche Ordner auf der Festplatte sichert. Dafür würdet ihr die zu sichernden Ordner irgendwo hinterlegen müssen, dazu einen Ordner zum hin sichern angeben und vielleicht noch ein paar zusätzliche Daten wie 'Wann wurde das letzte mal gesichert' oder 'Gab es Fehler beim letzten Durchgang'.

    Nun gibt es aber mehrere verschiedene Arten um einen Order zu sichern. (Sag ich jetzt mal so)
    • Intervall gesteuert. (Bsp. Immer nach 5Tagen zb.)
    • Überwacht. (Bsp. Immer wenn sich an dem Ordern etwas ändert)
    • ... Keine Ahnung, Bei Vollmond


    Jetzt könnte man seine Datenklasse in etwa so designen:

    Code:
        public abstract class AbstractBase
        {
            public string sDirectoryName { get; set; }
            public DateTime dtLastBackup { get; set; }
            public Exception exLastError { get; set; }
    
            public AbstractBase(string sDirName)
            {
                sDirectoryName = sDirName;
            }
    
            public abstract void vStartBackup();
        }
    Und so konkretisieren:

    Code:
        public class ObservedObject : AbstractBase
        {
            public override void vStartBackup()
            {
                Console.WriteLine("DoTheGagaThing");
            }
        }
    Um was es mir jetzt eigentlich geht, ist das Speichern und Erzeugen dieser Objekte.
    Angenommen die konkreten Klassen ObservedObject und IntervallObject unterscheiden sich dadurch, dass IntervallObject zusätzlich ein DateTime Property besitzt.
    (Das gibt an, in welchem Abstand gesichert werden soll.)

    Beim Speichern:
    Muss ich dann natürlich erkennen, um welches Objekt es sich jetzt wirklich handelt und das besagte DateTime Property ebenfalls wegspeichern.

    Beim Laden und Erzeugen:
    Ist es das selbe. Ich muss erkennen, dass es sich um ein IntervallObject handelt, und das DateTime Property auslesen und setzen.


    Wenn ich jetzt eine Datenbank zum speichern dieser "Objekte" nutze, muss ich (wenn ich alle in eine Tabelle) speichern will, natürlich ein entsprechendes Feld für das DateTime Property in die Definition aufnehmen, obwohl ich das gar nicht immer brauche. Auch wenn ich mal weitere Objektklassen die auf AbstractBase beruhen hinzufügen möchte, (die vielleicht andere Propertys brauchen) muss ich die ganze Datenbank tauschen. [Vorausgesetzt alles in einer Tabelle natürlich]

    Im großen und ganzen Frage ich mich wie man so etwas am sinnvollsten aufbaut.


    Nochmal die Kurzfassung:
    Speichern und Erzeugen von Objekten, die grundsätzlich gleich sind (Vererbung möglich?), aber individuelle Merkmale auf weißen.
    Diese Merkmale verhindern (quasi) ein immer gleiches Erzeugen, ein immer gleiches Speichern.


    Ich wäre für alle Vorschläge (zu diesem sicher einfachen Thema) offen, auch gerne mit einem anderen Beispiel.
    (Das hab ich mir gerade aus den Fingern gesogen, und es ist nicht sonderlich gut )


    Mit freundlichen Grüßen

    logihogi


    PS: Erkläre es auch gerne nochmal anders, sollte man nicht verstehen was ich den nun eigentlich will.

  • #2
    http://nhforge.org/
    Christian

    Comment


    • #3
      Also ich würde hierfür zwei Sachen bauen. Einen Job der immer läuft und das Sichern tatsächlich ausführt und eine Konfigurationsoberfläche. Für das Timen und Jobs gibt es fertige Libraries. Schau Dir mal Topshelf für die Jobs und Quartz für das Timing an. Im Prinzip hast Du dann schon mal den Teil der in bestimmten Intervallen von Dir geschriebenen Code aufruft.

      Fang danach erstmal an Deine einzelnen Sicherungsjobs runter zu tippen und denke nicht vorher über eine möglichst generische Architektur nach. Du wirst mit Sicherheit später feststellen dass sich die einzelnen Jobs doch gar nicht so ähnlich sind und sich der generische Anteil in Grenzen hält. Ich weiss das macht nicht ganz so viel Spaß als stundenlang über Architektur zu philosophieren, aber zu einem Ergebnis wirst Du auf jeden Fall schneller kommen. Sollten sich doch große Teile des Programms später überschneiden, dein Programm sollte ja überschaubar sein, kannst Du es immer noch in eine Basisklasse oder in Komposition zerlegen.

      Speichern und Laden teilt sich eigentlich immer in 2 Teile. Erstens überlege Dir welche Daten Du brauchst um den Job hoch- oder herunterzufahren. Dazu pure C# Klassen schreiben. Und danach kannst Du die hinschreiben wo Du willst. Der Code dazu sollte auf jeden Fall trivial sein.

      Ich hoffe ich habe Dir ein paar Tips geben können. Falls Du an manchen Stellen noch genauere Erklärungen brauchst frag einfach mal nach

      Comment


      • #4
        Originally posted by fanderlf View Post
        Also ich würde hierfür zwei Sachen bauen. Einen Job der immer läuft und das Sichern tatsächlich ausführt und eine Konfigurationsoberfläche. Für das Timen und Jobs gibt es fertige Libraries. Schau Dir mal Topshelf für die Jobs und Quartz für das Timing an. Im Prinzip hast Du dann schon mal den Teil der in bestimmten Intervallen von Dir geschriebenen Code aufruft.

        Fang danach erstmal an Deine einzelnen Sicherungsjobs runter zu tippen und denke nicht vorher über eine möglichst generische Architektur nach. Du wirst mit Sicherheit später feststellen dass sich die einzelnen Jobs doch gar nicht so ähnlich sind und sich der generische Anteil in Grenzen hält. Ich weiss das macht nicht ganz so viel Spaß als stundenlang über Architektur zu philosophieren, aber zu einem Ergebnis wirst Du auf jeden Fall schneller kommen. Sollten sich doch große Teile des Programms später überschneiden, dein Programm sollte ja überschaubar sein, kannst Du es immer noch in eine Basisklasse oder in Komposition zerlegen.

        Speichern und Laden teilt sich eigentlich immer in 2 Teile. Erstens überlege Dir welche Daten Du brauchst um den Job hoch- oder herunterzufahren. Dazu pure C# Klassen schreiben. Und danach kannst Du die hinschreiben wo Du willst. Der Code dazu sollte auf jeden Fall trivial sein.

        Ich hoffe ich habe Dir ein paar Tips geben können. Falls Du an manchen Stellen noch genauere Erklärungen brauchst frag einfach mal nach
        Erstmal danke für die schnelle Antwort. Ich muss aber nochmal betonen, dass ich das oben erwähnte nur als Beispiel geschrieben habe. Ich will das so nicht wirklich implementieren, ich wollt nur mein Verständnisproblem irgendwie greifbar machen.
        Wenn ich dich aber richtig verstehe, siehst du keinen großen Sinn darin den Aufbau seines Programmes im vorhinein klar festzulegen oder?
        Hab das früher nie gemacht, aber um so großer die Projekte werden um so eher muss ich gestehen, bin ich froh wenn zuvor alles gut durchdacht ist, oder zumindest eine Struktur erkennbar und durchgezogen ist.

        @Christian: NHibernate habe ich schon mal gehört. Ich werde mir das mal zu Gemüte führen.

        Comment


        • #5
          Wenn ich dich aber richtig verstehe, siehst du keinen großen Sinn darin den Aufbau seines Programmes im vorhinein klar festzulegen oder?
          Man sollte sich über seine geplanten Strukturen und Vorgänge schon im klaren sein, sonst arbeitest du u.U. mehrfach. Ein Zerlegung des Projektes in Module sollte erfolgen. Wobei man nicht auf Klassenebene runter gehen muss.
          Christian

          Comment


          • #6
            Trotzdem würde ich das erstmal runter tippen und dann ein refactoring machen. Dann weiss ich zumindest was meine Software leisten muss und kann das schön genug machen. Anders herum rate ich nur was meine Software vielleicht können soll und wie wir alle wissen kommt beim Implementieren dann doch immer noch die ein oder andere Feinheit dazu. Natürlich sollte Du jetzt im Vorfeld nicht total Spaghetticode tippen. Dann wirds auch schwer mit dem refactoring.

            Comment


            • #7
              Wenn ich dich aber richtig verstehe, siehst du keinen großen Sinn darin den Aufbau seines Programmes im vorhinein klar festzulegen oder?
              Das hast du vermutlich missverstanden. Du scheinst eine generische Lösung zu suchen bevor dir überhaupt klar ist ob du ein generisch lösbares Problem hast. An der Stelle macht es mehr Sinn ein Problem prototypenhaft zu implementieren, daran zu lernen und dann die passende Entscheidung zu treffen. Das schlimmste was dir passieren kann ist ein tolle Architektur zu basteln die irgendwelche theoretischen Probleme löst die du aber später gar nicht hast dafür aber später verhindert die tatsächlich vorhandenen konkreten Probleme zu lösen.

              An der Stelle wäre es dann hilfreich vielleicht erstmal mit einem Standard ORM zu beginnen um dann festzustellen ob ein OO Ansatz auf einer relationalen Datenbank für dich ein tragendes Konzept ist. Ich meine du beginnst ja bereits mit den Vorgaben einer objektorientierten Architektur aber einer relationalen Persistenz. Wieso sind die schon gesetzt? Diese Kriterien die dich dahin geführt haben sind meiner Meinung nach viel entscheidender als die Frage wie genau du jetzt eine einzelne Property persistierst.

              (Vererbung möglich?)
              Vererbung sollte nie die erste Wahl sein. Sondern nur dann gewählt werden wenn sich das nicht vernünftig als Komposition darstellen läßt. Bei deinem Beispiel fällt sofort auf das du eine Aufgabe (vStartBackup) mit den Daten die die Methode steuern vermischt. Du vermischt hier mindestens zwei Aspekte, Persistierung und das eigentliche Doing, die nicht zusammengehören.

              Comment


              • #8
                Originally posted by Ralf Jansen View Post
                Das hast du vermutlich missverstanden. Du scheinst eine generische Lösung zu suchen bevor dir überhaupt klar ist ob du ein generisch lösbares Problem hast. An der Stelle macht es mehr Sinn ein Problem prototypenhaft zu implementieren, daran zu lernen und dann die passende Entscheidung zu treffen. Das schlimmste was dir passieren kann ist ein tolle Architektur zu basteln die irgendwelche theoretischen Probleme löst die du aber später gar nicht hast dafür aber später verhindert die tatsächlich vorhandenen konkreten Probleme zu lösen.

                An der Stelle wäre es dann hilfreich vielleicht erstmal mit einem Standard ORM zu beginnen um dann festzustellen ob ein OO Ansatz auf einer relationalen Datenbank für dich ein tragendes Konzept ist. Ich meine du beginnst ja bereits mit den Vorgaben einer objektorientierten Architektur aber einer relationalen Persistenz. Wieso sind die schon gesetzt? Diese Kriterien die dich dahin geführt haben sind meiner Meinung nach viel entscheidender als die Frage wie genau du jetzt eine einzelne Property persistierst.



                Vererbung sollte nie die erste Wahl sein. Sondern nur dann gewählt werden wenn sich das nicht vernünftig als Komposition darstellen läßt. Bei deinem Beispiel fällt sofort auf das du eine Aufgabe (vStartBackup) mit den Daten die die Methode steuern vermischt. Du vermischt hier mindestens zwei Aspekte, Persistierung und das eigentliche Doing, die nicht zusammengehören.
                Besser hätte man es nicht zusammenfassen können

                Comment


                • #9
                  So aus meiner Erfahrung...

                  Ich seh das etwa so wie fanderif -tolles design hin oder her - für mich ist wichtig auch möglichst lange flexibel zu bleiben. Also erstmal die sicher zu lösenden (Teil) Aufgaben einzeln zu lösen - als als "Planung" weniger das Gesamtkonzept toll erarbeiten, sondern das Ding im Gegenteil herunterzubrechen/Zerlegen (nennt es meinetwegen Module )...

                  Hat in der Praxis min. 2 Vorteile - mehrere Leute können ggf. einfacher eingebunden werden, auf Änderungen die sicher kommen werden kann ggf. noch reagiert werden ohne in den Tisch zu beißen egal was der Vertrag sagt , 2/3 der Kunden wissen eigentlich nicht was sie wirklich wollen

                  Comment

                  Working...
                  X