Delphi-PRAXiS
Seite 4 von 7   « Erste     234 56     Letzte »    

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)

jfheins 22. Nov 2009 10:50

Re: Automaten in Source Code
 
Nein, das ist nicht der gleiche Aufwand.

Die Tabelle muss immer vollständig sein (leere Felder sieht man sofort => da fehlt was) bei dem case sieht man es nicht sofort wenn man was vergessen hat.

Und wenn man ein Ereignis hinzufügt, muss man sich bei der Tabelle Gedanken machen, wass in jedem Zustand passieren soll - beim case läuft man Gefahr, einen Zustand zu vergessen (Dann wird ja der else-Zweig ausgeführt), und man hat möglicherweise einen Bug.

Und die Tabelle kann man gut seperat validieren. z.B. eine Excel-Arbeitsmappe die die Tabelle überprüft und ggf. auf Sackgassen oder nicht zusammenhängende Bereiche aufmerksam macht.

Das ganze wird natürlich wichtiger, je komplexer das ganze wird. Ob diese Grenze (oberhalb der man bereit ist, eine zusätzliche Abstraktion einzuführen) bei 3 Ereignissen und 4 Zuständen schon erreicht ist, ist subjektiv.

Btw.: Zu der Zustandsmatrix gehört eigentlich auch eine Vorgangsmatrix oder sowas - die Zustandsmatrix gibt zu einem Zustand und einem Ereignis den neuen Zustand an, und die Vorgangsmatrix gibt die Aktion an, die passieren soll ... oder nicht?

SebE 22. Nov 2009 11:32

Re: Automaten in Source Code
 
Die "Vorgangsmatrix" steckt in ProcessState:

Delphi-Quellcode:
State := CoStartState.Create;
While Not State.IsStopState Do Begin
  State.DoProcessState();
  State := State.NextState;
End;

Zitat:

Nein, das ist nicht der gleiche Aufwand.

Die Tabelle muss immer vollständig sein (leere Felder sieht man sofort => da fehlt was) bei dem case sieht man es nicht sofort wenn man was vergessen hat.

Und wenn man ein Ereignis hinzufügt, muss man sich bei der Tabelle Gedanken machen, wass in jedem Zustand passieren soll - beim case läuft man Gefahr, einen Zustand zu vergessen (Dann wird ja der else-Zweig ausgeführt), und man hat möglicherweise einen Bug.
Das ist ein Streitpunkt, aus dem wir nicht rausfinden.
Ich sage, es ist der gleiche Aufwand.

Wenn man "viele" Zustände hat, ist man gut daran einen Graphen zu zeichnen, wenn ich diesen ändere, WEIß ich sofort, wo ich in der Tabelle/Case etwas zu ändern habe.

Zur Klarstellung (nur weil das bestimmte Personen evtl so sehen): Ich habe mich nie GEGEN die Tabellenlösung als solches ausgesprochen.
Ich finde die Case (vor allem in unserem kleinen Beispiel) ebenwürdig.

Das kommt auch daher, dass die Case-Variante immer mächtiger ist.

Kleines Beispiel:
Man nehme an, man "füttert" seinen Automaten nicht mit einer Liste von Charactern (String) sondern mit einer Liste von zwei, drei, ... Zeichen pro Terminalsymbol.

Eingabe: "ABC#32DE", hier soll #32 EIN Smbol darstellen.

Bitte keine Bezüge zu "Bändern" von denen der Automat liest.

Hier benötigt man einen Scanner mit CASE.

Alternative: Man könnte natürlich den Scanner wiederum als separaten Automaten modellieren, der pro Aufruf ein TerminalSymbol rauswirft.

Meflin 22. Nov 2009 11:43

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Es ist nicht die Aufgabe eines jeden Zustandes, sich um den nächsten zu kümmern.

Wessen Aufgabe denn dann? Was man bei gutem OOP ja garnicht haben will sind sg. "God-Classes"... Insofern ist das Vorgehen garnicht so verkehrt.

SebE 22. Nov 2009 11:56

Re: Automaten in Source Code
 
Das ist das Thema, welches mich interessiert.

Kannst du mir Quellen geben, die die (Entwicklungs-)Prinzipien des Paradigmas erklären, dass zB "God-Classes" nicht gern gesehen werden.

Ein Beispiel (erstellen einer Liste):

1. Man erstellt nur die Elemente der Liste und diese organisiert sich "indirekt" selbst.
2. man erstellt Elemente, die IHRE eigene Aufgabe (und nur DIESE) erfüllen; und dazu eine "Schale", die die Organisation übernimmt

Was ist an Punkt 2 auszusetzen (mehr Schreibarbeit mal Außen vor gelassen).

Ich würde 1. bevorzugen, da zB die Suche in 2. über die Elemente funktioniert, die Elemente es aber überhaupt nicht zu interessieren hat.
Wenn sich nun die Organisation ändert, bekommen die Elemente nichts davon mit (was eigentlich erwünscht ist)

Prinzipien der OO sind doch:
- Jedes Objekt hat (s)eine Aufgabe
- Minimale Sichtbarkeiten
- ...

Liste darf (durch euch) erweitert werden

SebE 22. Nov 2009 12:01

Re: Automaten in Source Code
 
Ich seh grad auf Wiki (http://de.wikipedia.org/wiki/God_object):

God-Object = ein Objekt, dass "zu viel kennt".

Das entspricht aber der hier vorgestellten Lösung.
Ein ListenElement, welches seinen Nächsten kennt (und in unserem Automaten sogar noch "managed").

Uwe Raabe 22. Nov 2009 12:20

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Ich seh grad auf Wiki (http://de.wikipedia.org/wiki/God_object):

God-Object = ein Objekt, dass "zu viel kennt".

Das entspricht aber der hier vorgestellten Lösung.
Ein ListenElement, welches seinen Nächsten kennt (und in unserem Automaten sogar noch "managed").

Das ist Ansichtssache: Das State-Objekt kennt nur seinen Zustand (nicht, wie er erreicht wurde) und unter welchen Bedingungen welcher Folge-Zustand erreicht wird. Alle anderen Zustände sind ihm fremd. Das ist ein klar abgegrenzter Zuständigkeitsbereich.

Im Gegenzug dazu müssen die Case-Anweisung und die Tabelle immer alle Zustände und möglichen und nicht-möglichenn Transitionen kennen.

Übrigens: hier gibt es eine schöne visuelle OOP-Implementierung einer Statemachine.

SebE 22. Nov 2009 12:28

Re: Automaten in Source Code
 
Zitat:

Das ist Ansichtssache: Das State-Objekt kennt nur seinen Zustand (nicht, wie er erreicht wurde) und unter welchen Bedingungen welcher Folge-Zustand erreicht wird
Das ist ja nicht das Problem, mir ging es um die Organisation - sprich: die Erzeugung der Folgezustände.

Es ist (in meinen Augen) NICHT die Aufgabe eines Zustandes den nächsten zu erstellen und ihn damit zu organisieren.

Es braucht einen "Hüter", der die Aufgabe der Tabelle oder CASE übernimmt, also den Automatengraphen "simuliert".

Meflin 22. Nov 2009 12:31

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Es ist (in meinen Augen) NICHT die Aufgabe eines Zustandes den nächsten zu erstellen und ihn damit zu organisieren.

In Delphi muss halt nunmal irgendwer die Instance erzeugen. Und da ist es immernoch besser, eine Klasse erstellt ihre Folgezustände, als eine Klasse erzeugt ALLE Zustände. Optimal in dem Sinne wäre es vielleicht, class methods zu verwenden und beim ersten Aufruf den Zustand sich selbst erzeugen zu lassen. Andere Sprachen sind in der Hinsicht halt konsequenter...

markusj 22. Nov 2009 12:32

Re: Automaten in Source Code
 
Zitat:

Zitat von SebE
Wie soll denn das aussehen?

Ist mein abstrakter Zustand vom Typ Basisklasse und jeder aktuelle (reale) Zusatnd dann von einer abgeleiteten Klasse?
(das wären sehr viele speicheroperationen)

Ich bitte um Aufklärung

Genau so. Wenn man die einzelnen Zustände dann noch als Singleton anlegt, erspart man sich auch das ständige Erzeugen und Zerstören von Objekten, was der Geschwindigkeit zugute kommt.
Je nach Implementierung der Zustände kann man entweder eine Basisklasse verwenden und nur noch einzelne Methoden in den Kindklassen überschreiben, oder aber man verwendet nur ein Interface.

mfG
Markus

SebE 22. Nov 2009 12:46

Re: Automaten in Source Code
 
ich spreche Sprachunanhängig, es geht mir jetzt rein um OOP, OO oder OOT (wie mans nennen will).

Zitat:

Zitat von Meflin
Zitat:

Zitat von SebE
Es ist (in meinen Augen) NICHT die Aufgabe eines Zustandes den nächsten zu erstellen und ihn damit zu organisieren.

In Delphi muss halt nunmal irgendwer die Instance erzeugen. Und da ist es immernoch besser, eine Klasse erstellt ihre Folgezustände, als eine Klasse erzeugt ALLE Zustände. Optimal in dem Sinne wäre es vielleicht, class methods zu verwenden und beim ersten Aufruf den Zustand sich selbst erzeugen zu lassen. Andere Sprachen sind in der Hinsicht halt konsequenter...

dazu:

Zitat:

Wessen Aufgabe denn dann? Was man bei gutem OOP ja garnicht haben will sind sg. "God-Classes"... Insofern ist das Vorgehen garnicht so verkehrt.
Die Lösung "Jeder Zustand erzeugt seinen Nächsten" ist eine God-Class-Lösung.

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)

Das entspricht (soweit ich das einschätzen kann) einer guten OO.
Ich lerne selbst gerade erst damit umzugehen (ich bastle mir eine SymbolTabelle für einen Compiler rein OO).
Da hat man so manche philosophische Halbe Stunde :-)

Um Bezug zu nehmen auf das eigentliche Thema: die OO-Lösung die hier vorgestellt wurde ist unübersichtlich, das die Organisation sehr stark verteilt wurde (auf #Zustände-viele Klassen).


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:45 Uhr.
Seite 4 von 7   « Erste     234 56     Letzte »    

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