Delphi-PRAXiS
Seite 5 von 7   « Erste     345 67      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Automaten in Source Code (https://www.delphipraxis.net/143671-automaten-source-code.html)

Meflin 22. Nov 2009 12:54

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Mein "eleganter" und "OO-Korrekter" Lösungsvorschlag: 2 Klassen.

- Klasse Zustand (diese speichert (organisiert) die Aktion, die Ausgabe (falls Mealy-Automat) und eventuall seinen Folgezustand)

- Klasse Tabelle/Case/Graph (managed alle Zustände, interne Realisierung ist persönliche Sache)

Diese Lösung ist noch wesentlich "God-Classiger". Ist das nicht eigentlich offensichtlich :gruebel:

SebE 22. Nov 2009 12:58

Re: Automaten in Source Code
 
Weil die - ich nenn sie jetzt Graph-Klasse - über die Zustände "herrscht".

Eingentlich nicht.
Es ist doch nicht schlimm, wenn eine Klasse, andere Klassen handelt.

Es geht doch bei OO um "Aufgaben-Verteilung" und die ist mir meiner Lösung gut umgesetzt.

"von unten nach oben" entwickeln.
Erst due Zustände modellieren und danach die Verbindung zwischen ihnen (Grapf)

Khabarakh 22. Nov 2009 13:44

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Weil die - ich nenn sie jetzt Graph-Klasse - über die Zustände "herrscht".

So ähnlich wie Gott über seine Schäfchen ;) ?

Ich denke, wir könnten uns auf folgende Regeln einigen, die mehr oder weniger schon genannt wurden:
  • Jede State-Klasse kennt nur die Klassen ihrer Folgezustände ("kennen" beinhaltet natürlich auch "erzeugen können").
  • Außerhalb davon ist nur die Klasse des Startzustandes und das Interface bekannt.

Ich glaube, du nimmst das Problem immer noch zu holistisch in Angriff. Den Automaten zu Beginn einmal aufzumalen, ist natürlich alles andere als falsch, aber während der Implementierung darf niemals der gesamte Graph in deinem Kopf herumschwirren, sondern immer nur direkt voneinander abhängige Bestandteile.

SebE 22. Nov 2009 13:57

Re: Automaten in Source Code
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von SebE
Weil die - ich nenn sie jetzt Graph-Klasse - über die Zustände "herrscht".

So ähnlich wie Gott über seine Schäfchen ;) ?

Nein eine Gott-Klasse übernimmt jede (oder zumindest zu viel) Aufgabe(n).
"Meine" Graphklasse übernimmt nur die Handhabung, was die Zustände intern machen, ist ihr Wurst.

Zitat:

Ich denke, wir könnten uns auf folgende Regeln einigen, die mehr oder weniger schon genannt wurden:
  • Jede State-Klasse kennt nur die Klassen ihrer Folgezustände ("kennen" beinhaltet natürlich auch "erzeugen können").
  • Außerhalb davon ist nur die Klasse des Startzustandes und das Interface bekannt.

Eben nicht.

Meflin 22. Nov 2009 14:31

Re: Automaten in Source Code
 
Hää?? Deine Klasse erstellt ALLE Instances und ist damit weniger "Gott" als die Version, wo jede Instance die Instances der Folgezustände erstellt (und damit einen wirklich wesentlich eingeschränkteren Funktionsumfang & "Sichtweite" hat). Das ergibt einfach keinen Sinn. Khabarakh hat schon ganz recht... "Deine" Klasse kennt ALLES, in der von uns vorgeschlagene Version kennt jede Instance ihre Folgezustände... wo ist also hier der Gott?? Entweder du hast es nicht verstanden, oder aber ich verstehe einfach nicht was deine Klasse nun eigentlich machen soll...

Steuerungsklassen sind IMMER ein sehr sehr deutlicher Indikator für schlechte Klassenstruktur. Ja, immer :P

markusj 22. Nov 2009 14:34

Re: Automaten in Source Code
 
Zumindest in unserer Softwaretechnik-Vorlesung wurde die Variante "Jeder Zustand kennt/erzeugt _nur_ seinen Nachfolger" favorisiert. Allgemeiner Strukturen/Aufgaben wurde dabei in der Elternklasse implementiert, die zustandsspezifischen Methoden wurden erst in den einzelnen Zustandsklassen implementiert.
Im übrigen bietet sich bei dieser Variante auch gleich den Einsatz von Singletons an ...

Letztendlich ist es auch immer eine Frage des Geschmacks und der Problemkomplexität, gerade das zerlegen in die einzelnen Zustände verteilt den Aufwand und die Komplexität gleichmäßiger als ein schwer wartbares Case.

mfG
Markus

SebE 22. Nov 2009 14:43

Re: Automaten in Source Code
 
Zitat:

Zitat von Meflin
Hää?? Deine Klasse erstellt ALLE Instances und ist damit weniger "Gott" als die Version, wo jede Instance die Instances der Folgezustände erstellt (und damit einen wirklich wesentlich eingeschränkteren Funktionsumfang & "Sichtweite" hat). Das ergibt einfach keinen Sinn. Khabarakh hat schon ganz recht... "Deine" Klasse kennt ALLES, in der von uns vorgeschlagene Version kennt jede Instance ihre Folgezustände... wo ist also hier der Gott?? Entweder du hast es nicht verstanden, oder aber ich verstehe einfach nicht was deine Klasse nun eigentlich machen soll...

Vom Zeitpunkt der Entwicklung aus gesehen, kennt dein Zustand auch jeden anderen!
(da er ihn ja (rekursiv) erzeugt)

Gott-Klasse heißt doch nichts anderes, als:
Ich entwickle etwas imperativ (am besten noch unstrukturiert) und schmeiß alles in eine Klasse (die macht alles -> Gott)

Meine Graph-Klasse hat aber nur EINE Aufgabe (es ist egal, wen sie alles KENNT), nämlich Organisation.
Was die Elemente der organisatorischen Einheit (Zustände) machen, ist der Graphklasse egal (nicht Gott, da Aufgaben weitergegeben wurden).

Nur weil eine Klasse mehrere (auch verschiedene) Klassen handhabt, wird sie nicht zu einer Gott-Klasse.

Zitat:

Steuerungsklassen sind IMMER ein sehr sehr deutlicher Indikator für schlechte Klassenstruktur. Ja, immer :P
Das versteh ich überhaupt nicht.

Wenn ich keine Klasse erstellen darf, die etwas steuert (auch andere Klassen), dann mach ich es doch imperativ (max. strukturiert) aber nicht OO!

Zusammenfassung: "Deine"/"Eure" Lösung halte ich für eine Gott-Klassen-Lösung, da ihr für mehrere Aufgaben EINE Klasse habt.

Uwe Raabe 22. Nov 2009 14:58

Re: Automaten in Source Code
 
Es ist übrigens nicht zwingend so, daß die Folge-Zustände von dem aktuellen Zustand erzeugt werden - sie werden lediglich von ihm zurückgegeben.

Ein denkbares Beispiel dafür ist ein Warte-Zustand W. Dieser wartet eine bestimmte Zeit T auf ein Ereignis E und gibt beim Eintreten den Zustand A zurück und bei einem Timeout den Zustand B. Die Zustände A und B können zusammen mit dem Ereignis E (Anonyme Funktionen gehen da ganz hervorragend) und einer Zeit T z.B. beim Erzeugen oder Eintreten in den Zustand W übergeben werden. Damit läßt sich dieser Wartezustand flexibel an unterschiedlichen Stellen einsetzen, ohne für jede Möglichkeit eine eigene Zustandsklasse zu deklarieren.

Ich verwende eine solche OOP-State-Machine gerade in einer Ablaufsteuerung und das funktioniert geradezu hervorragend. Gerade das Manipulieren einzelner Ablaufstränge, wie das Einfügen von Zwischenzuständen, Reagieren auf Fehler mit nachfolgendem Wiederaufsetzen ist wesentlich übersichtlicher als es mit einer Case- oder Tabellen-Lösung möglich wäre.

Wenn jemand Interesse an dem Artikel "Object-Oriented State Machine" von Julian Bucknell aus dem Delphi Magazine hat (Untertitel: Getting rid of case statements) - kurze PM an mich.

SebE 22. Nov 2009 15:08

Re: Automaten in Source Code
 
Zitat:

Es ist übrigens nicht zwingend so, daß die Folge-Zustände von dem aktuellen Zustand erzeugt werden - sie werden lediglich von ihm zurückgegeben.
...und nicht mehr.

Wenn ein Zustand in einen Anderen übergeht, löscht sich der aktuelle, oder?
Das verstößt doch sicher auch gegen irgendwelche Regeln (ich erzeuge im Lauf immer die SELBEN Objekte und lösche sie wieder)

Uwe Raabe 22. Nov 2009 15:42

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Zitat:

Es ist übrigens nicht zwingend so, daß die Folge-Zustände von dem aktuellen Zustand erzeugt werden - sie werden lediglich von ihm zurückgegeben.
...und nicht mehr.

Das ist deine Interpretation - ich würde das nicht so einschränken. Es wird ein Folge-Zustand zurückgegeben. Das sagt aber nichts darüber aus, wo er herkommt.

Zitat:

Zitat von SebE
Wenn ein Zustand in einen Anderen übergeht, löscht sich der aktuelle, oder?
Das verstößt doch sicher auch gegen irgendwelche Regeln (ich erzeuge im Lauf immer die SELBEN Objekte und lösche sie wieder)

Effizienterweise implementiert man eine solche State-Machine dann auch nicht über Objekt-Variablen sondern über Interfaces. Wie die Lebensdauer der implementierenden Klassen-Instanzen geregelt ist (Referenzzählung, Pool oder Garbage Collection), kann dem Automaten dann nämlich egal sein.

Und nebenbei: Hiermit distanziere ich mich von der Formatierung in deinem Zitat.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 Uhr.
Seite 5 von 7   « Erste     345 67      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz