State Pattern als Enum?

Rudolf

Bekanntes Mitglied
Hi,

ich kenne das State Pattern als Muster mit normalen Klassen ohne Enumeration. Kann man das State Pattern mit einer enum Klasse umsetzen?

Sehe auf den ersten Blick keine Möglichkeit folgendes sementisch gleich als enum zu realisieren

Java:
public class Test {
	public static void main(final String[] args) {
		new Test().start();
	}
	State state = new StateA(this);
	private void start() {
		state.execute();
	}
	public void setState(State state) {
		this.state = state;
	}
}

abstract class State {
	protected final Test invoker;
	protected State(Test invoker) {
		this.invoker = invoker;
	}

	public abstract void execute();
}

class StateA extends State {
	protected StateA(Test invoker) {
		super(invoker);
	}
	@Override
	public void execute() {
		System.out.println("calcing...");
		final int result = 5;
		final StateB newState = new StateB(result, invoker);
		invoker.setState(newState);
	}
}

class StateB extends State {
	private final int value;
	protected StateB(int result, Test invoker) {
		super(invoker);
		value = result;
	}
	@Override
	public void execute() {
		System.out.println(value);
	}
}

Sowas wäre eine ähnliche Umsetzung, aber ist syntaktisch fehlerhaft:

Java:
public class Test {
	public static void main(final String[] args) {
		new Test().start();
	}
	State state = State.StateA;
	private void start() {
		state.execute(this);
	}
	public void setState(State state) {
		this.state = state;
	}
}

enum State {
	StateA {
		@Override
		public void execute(Test invoker) {
			System.out.println("calcing...");
			final int result = 5;
			invoker.setState(StateB);
			StateB.setValue(result);
		}
	},
	StateB {
		private final int result;
		public void setValue(int value) {
			result = value;
		}
		@Override
		public void execute(Test invoker) {

		}
	};
	public abstract void execute(Test invoker);
}

Kennt jemand eine bessere Umsetzung?
 
Zuletzt bearbeitet:

Empire Phoenix

Top Contributor
Ich würde evtl im sinne der flexibilität, udnd amit nicht alles in einer class ist nen Interfae State machen, dann normale classen nehmen, und ne Enum um die gültigen States alle an einem punkt gelsitet zu haben.

Weil wenn ud das so amchst und zb nen state der 5 unterklassen braucht und 1k zeilen lang ist hast wirds minmal unübersichtlich.
 

Rudolf

Bekanntes Mitglied
Ich würde evtl im sinne der flexibilität, udnd amit nicht alles in einer class ist nen Interfae State machen, dann normale classen nehmen, und ne Enum um die gültigen States alle an einem punkt gelsitet zu haben.

Weil wenn ud das so amchst und zb nen state der 5 unterklassen braucht und 1k zeilen lang ist hast wirds minmal unübersichtlich.

Wie meinst du Übersicht? Kannst n Beispiel mit deiner Enum geben?
 

sambalmueslie

Bekanntes Mitglied
Ich finde es allgemein gesagt nicht sehr schön, wenn ENUM's irgendwelchen Funktionscode enthalten.
Das sorgt - IMHO - nur für Verwirrung und bietet nichts wesentlich eleganteres, als mit Klassen direkt zu arbeiten.

Ich kenne eine Lösung, da wird jeder Zustand als konkrete Klasse implementiert (Zustandsmaschine)
und für das unterscheiden der Zustände wird ein Enum herangenommen. Beispielsweise um von Zustand A nach Zustand B zu wechseln.
 
F

Firephoenix

Gast
Ich finde es allgemein gesagt nicht sehr schön, wenn ENUM's irgendwelchen Funktionscode enthalten.
Das sorgt - IMHO - nur für Verwirrung und bietet nichts wesentlich eleganteres, als mit Klassen direkt zu arbeiten.

Ich kenne eine Lösung, da wird jeder Zustand als konkrete Klasse implementiert (Zustandsmaschine)
und für das unterscheiden der Zustände wird ein Enum herangenommen. Beispielsweise um von Zustand A nach Zustand B zu wechseln.

Tatsächlich sind Enums ein extrem brauchbarer Weg um Singletons zu realisieren:
Singleton in Java – the proper way Electrotek

Allerdings ist das Verhalten dann allgemein an das Enum gebunden, beim State Pattern will man ja in der Regel unterschiedliches Verhalten ohne ewiges if(state == ...) bzw switch(state) mittels polymorphie erreichen -> mehrere Klassen.

Gruß
 

Rudolf

Bekanntes Mitglied
Kann man als Fazit aussagen:

Wenn ein erweitertes Boolean-Feld gebraucht wird, bei dem man wenige Unterscheidungen macht, wie z. B. bei

Java:
enum Day {
Montag,Dienstag,Mittwoch;
}

dann nutzt man das enum aber für ein echtes State Pattern ist das Coding mit eigenen Klassen der bessere Weg?
 
J

JohannisderKaeufer

Gast
Die Frage sollte doch eher sein was dies:
Java:
enum Day {
Montag,Dienstag,Mittwoch;
}

bringen soll?

Damit kann man eigentlich nur was Anfangen, wenn man sich nicht an ein Statepattern orientieren möchte.
Java:
if(day == Montag) ...
if(day == Mittwoch)...
switch(day)
Montag: ...
Dienstag: ...

Enums kann man gut und Sinnvoll für State-Pattern benutzen.
Man muß nur ein paar Dinge beachten:

Mit Enums ist die ganze Geschichte Abgeschlossen.
Java:
enum Day {
Montag, ..., Sonntag
}
Es kann nicht mehr mit Weihnachten, Ostern, Neujahr und sonstigen besonderen Tagen erweitert werden, da das Enum nur Montag bis Sonntag kennt.

Ein Enum darf/sollte keinen "State" beinhalten! Es sollte Stateless sein.
Java:
StateB {
        private final int result;
        public void setValue(int value) {
            result = value;
        }

Also das Feld result ist Fehl am Platz.
Man stelle sich nur vor, daß man mehrere Threads hat, wobei beide ein verschiedenes value setzen und erst dann eine execute Methode aufgerufen wird.

Das Enum Day kann z.B. einen Konstruktor haben, so daß ein Wochentag eine Nummer "Tag der Woche" bekommt.
Dieser State ist dann allerdings Fix und wird beim Initialisieren gesetzt.

Bei vielen Werten und langen Methoden kann das ganze Recht schnell unübersichtlich werden. Bei einer Lösung mit einzelnen Klassen verteilt sich das auf viele Dateien, die ihrerseits übersichtlich bleiben. Das ganze bleibt erweiterbar. Zu den Tagen Montag bis Sonntag, kann auch ein Weihnachten hinzugefügt werden.

Bei enums hat man weniger Sorgen bzgl. der Initialisierung der States gegenüber einzelnen Klassen, die man dann allerdings cachen kann oder on Demand initialisieren. Bei on Demand erzeugt man dann allerdings auch jährlich jeweils über 50 Montage ... Sonntage.

Wie also leicht zu erkennen ist, gibt es nicht wirklich ein Allheilmittel.


Anbei noch ein Video bei dem ein paar Punkte bzgl. dem Thema behandelt werden.

"The Clean Code Talks -- Inheritance, Polymorphism, & Testing" - YouTube
 

sambalmueslie

Bekanntes Mitglied
Tatsächlich sind Enums ein extrem brauchbarer Weg um Singletons zu realisieren:
Singleton in Java – the proper way Electrotek

Hm nette Idee, aber enum heißt auf deutsch nun mal Aufzählung(Menge) und Singleton ist eine "einelementige Menge" und damit finde ich die Lösung verwirrend und fällt für mich eher in die Kategorie, freaky C++ Code (why simple, if you can do it freaky). So wie ich aber z.b. Robert C. Martin mit Clean Code verstanden habe muss ein guter Code möglichst verständlich geschrieben sein und damit werde ich diese Lösung nicht einsetzen.
 

Qler

Mitglied
[OT]
bei einem enum als singleton geht es vorallem darum, dass keine zweite instanz (über reflections, serialization o.ä.) erzeugt werden kann! für sicherheitskritischen- code ist das evtl von bedeutung!
[/OT]
 
N

nillehammer

Gast
sambalmueslie hat gesagt.:
Hm nette Idee, aber enum heißt auf deutsch nun mal Aufzählung(Menge) und Singleton ist eine "einelementige Menge" und damit finde ich die Lösung verwirrend und fällt für mich eher in die Kategorie, freaky C++ Code (why simple, if you can do it freaky). So wie ich aber z.b. Robert C. Martin mit Clean Code verstanden habe muss ein guter Code möglichst verständlich geschrieben sein und damit werde ich diese Lösung nicht einsetzen.
Ich finde das Singleton-Enum-Pattern jetzt nicht unverständlich. Jedenfalls nicht unverständlicher als dieser ganze static-Kram, den man sonst macht, um Singletons zu realisieren. Das Pattern wird von Joshua Bloch (Mitentwickler des JDK) ausdrücklich in seinem Buch empfohlen. Ich werde es also in den seltenen Fällen, wo ich Singletons brauche, benutzen.

Und zur Ursprungsfrage:
Java:
enum State {
    StateA {
        @Override
        public void execute(Test invoker) {
            System.out.println("calcing...");
            final int result = 5;
            invoker.setState(StateB);
            StateB.setValue(result);
        }
    },
    StateB {
        private final int result;
        public void setValue(int value) {
            result = value;
        }
        @Override
        public void execute(Test invoker) {
 
        }
    };
    public abstract void execute(Test invoker);
Lager die abstrakte excecute-Methode in ein public Interface "State" aus. Lass Deine enum dieses Interface implementieren. Programmiere nur gegen dieses Interface. Dass Deine enum package-private ist, ist schonmal ein guter Schritt in diese Richtung. Wenn Dir die State-Enum irgendwann doch zu unflexibel ist, kannst Du sie leicht austauschen, weil der Client nur das Interface sieht.
 
M

maki

Gast
Code/Logik in Enums zu haben ist nix ungewöhnliches in Java, ganz im Gegenteil, da ist nix "tricky" daran, sondern eher Standard in Java.

Empfehle das Josh Blochs "Effective Java 2nd Edition" als Lektüre.

Allerdings ist das State Patterns kein guter Kandidat, eben wegen des Zustandes.
Das Algorythm Pattern dagegen wird meistens als Enum implementiert, bietet sich ja direkt dafür an.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C java- state of the art ?!? Allgemeine Java-Themen 0
vodkaz state machine Allgemeine Java-Themen 1
T Global state Allgemeine Java-Themen 12
G Methodenaufrufe wie state maschine Allgemeine Java-Themen 4
J Aktionen im State-Design-Modell Allgemeine Java-Themen 3
S State-Of-The-Art bei Datenbankzugriffen Allgemeine Java-Themen 10
A State-of-the-Art Techniken für Desktop Programme ? Allgemeine Java-Themen 3
MQue Vector<State> Allgemeine Java-Themen 2
mihe7 equals und instanceOf pattern matching Allgemeine Java-Themen 7
L Pattern Eventhandler Allgemeine Java-Themen 5
EinNickname9 Best Practice Singleton und Singleton mit Instanz zu anderer Klasse -Pattern Allgemeine Java-Themen 30
Z MVC Pattern - sinnvolle Integration Allgemeine Java-Themen 6
J Meinung zum verwendeten Design Pattern Allgemeine Java-Themen 4
Kirby.exe Filename nach bestimmtem Pattern durchsuchen Allgemeine Java-Themen 5
Meeresgott Best Practice "Spezifisches" Factory Pattern ? Allgemeine Java-Themen 1
H Strategy Pattern - changeColor() Methode - input rgd oder hex einlesen Allgemeine Java-Themen 1
M Vaadin MVP Pattern Allgemeine Java-Themen 1
N Java MVC Pattern richtig anwenden Allgemeine Java-Themen 24
M OOP Design Pattern - "extends Observable implements Observer" Allgemeine Java-Themen 0
K Factory Pattern: Mit Generics umgehen Allgemeine Java-Themen 6
perlenfischer1984 Welches Design Pattern ist geegneit. Allgemeine Java-Themen 7
perlenfischer1984 Hilfe bei Design (Pattern) Allgemeine Java-Themen 5
J Compilerfehler bis in java.util.regex.Pattern... Allgemeine Java-Themen 2
B MVC-Pattern größeres Beispiel Allgemeine Java-Themen 16
GreenTeaYT Verstehe nicht ganz das Observer Pattern in einer Arrayliste? Allgemeine Java-Themen 3
L Erste Schritte Java Date Format Pattern bestimmten Allgemeine Java-Themen 2
D Pattern mit Pattern vergleichen Allgemeine Java-Themen 3
D OOP Design Pattern für GUI - Datenbank Anwendung Allgemeine Java-Themen 1
S Hilfe bei geeignetem Pattern (Decorierer) Allgemeine Java-Themen 2
F Welches Design Pattern? Allgemeine Java-Themen 3
J Pattern aus String entfernen Allgemeine Java-Themen 2
S Pattern.Match Suche: For Schleife einbinden und in Liste schreiben Allgemeine Java-Themen 3
D Variablen zur Laufzeit global speichern (Registry Pattern?) Allgemeine Java-Themen 6
M massenhaft verschiedene Date-Pattern Allgemeine Java-Themen 3
Guybrush Threepwood Pattern gesucht: Punkt ohne Leerzeichen dahinter Allgemeine Java-Themen 3
turmaline OOP Decorater Pattern für Varifikationsverhalten Allgemeine Java-Themen 13
T HTML Tag Position mittels Pattern ermitteln Allgemeine Java-Themen 7
X Datentypen Prozentualer Abgleich zwischen 2 Strings (Pattern?) Allgemeine Java-Themen 3
H Pattern.compile Syntax Allgemeine Java-Themen 15
B RegEx: (Um-)formulieren eines Pattern zur Identifizierung komplexer URLs Allgemeine Java-Themen 7
D [Drag&Drop] Design-Pattern-Frage Allgemeine Java-Themen 4
T Pattern für Benutzer-Gruppen, RMI Allgemeine Java-Themen 5
E Super erzwingen, konzept/pattern gesucht. Allgemeine Java-Themen 8
H Problem mit der Klasse Pattern - Regulärer Ausdruck Allgemeine Java-Themen 2
Eldorado Meinung zu einem abgewandelten MVC-Pattern Allgemeine Java-Themen 2
R Matcher - Pattern mit belibigem Anfang Allgemeine Java-Themen 2
H Bestimmten String mit Pattern und Matcher herauslesen => kein erfolg Allgemeine Java-Themen 9
I Pattern zum Erweitern existierender Objekte Allgemeine Java-Themen 4
I Template Method pattern mit "geschützten Methoden" Allgemeine Java-Themen 5
T Pattern: Passive View Allgemeine Java-Themen 2
K Verständnisprobleme bei Observer-Pattern mit größerem Datenmodell Allgemeine Java-Themen 32
T Pattern: Greedy, Reluctant, Possessive Allgemeine Java-Themen 4
S Hilfe bei Pattern Allgemeine Java-Themen 5
N Registry Pattern Allgemeine Java-Themen 7
Tandibur Denkfehler bei Pattern.matches? Allgemeine Java-Themen 3
Tandibur pattern dynamisch vorkompilieren Allgemeine Java-Themen 9
A Observer Pattern: feuern bei neuer Referenz-Zuweisung? Allgemeine Java-Themen 8
N Pattern Allgemeine Java-Themen 11
Iron Monkey Pattern - Matcher - Problem Allgemeine Java-Themen 3
ruutaiokwu welches design pattern? frage an die oo-experten unter euch... Allgemeine Java-Themen 3
G Accordion Design Pattern Frage Allgemeine Java-Themen 2
hdi Hilfe beim Design (Stichwort OO, Pattern, ...) Allgemeine Java-Themen 11
U Verständnisschwierigkeiten Observer Pattern Allgemeine Java-Themen 18
H2SO3- String(pattern) von SimpleDateFormat auslesen Allgemeine Java-Themen 7
M Problem mit Pattern Allgemeine Java-Themen 3
N Welches design pattern? Allgemeine Java-Themen 8
B Pattern gesucht, Programm Optionen, Casten vermeiden Allgemeine Java-Themen 3
D Welches Pattern kann ich nutzen? Allgemeine Java-Themen 9
J Suche regex-Pattern fuer Liste von Zahlen zwischen 0-100 Allgemeine Java-Themen 6
G Sequenzdiagramm Dao Pattern Allgemeine Java-Themen 3
D Observer/Observable Pattern vs. Listener-Konzept Allgemeine Java-Themen 4
S regex-Pattern Ausdruck negieren Allgemeine Java-Themen 2
J Pattern eines Textes Allgemeine Java-Themen 4
M Java Garbage Collector Frage (Singleton Pattern) Allgemeine Java-Themen 13
Y Pattern Problem Allgemeine Java-Themen 2
G UML-Diagramme mit DAO Pattern Allgemeine Java-Themen 7
S Pattern regex Allgemeine Java-Themen 2
G Composite, Design Pattern, printTree Allgemeine Java-Themen 42
J Regex Pattern Problem Allgemeine Java-Themen 12
P MVC Pattern Allgemeine Java-Themen 31
C Pattern für Kommunikation gesucht Allgemeine Java-Themen 3
G Frage zu MVC Pattern Allgemeine Java-Themen 6
J Pattern und Regex Allgemeine Java-Themen 2
L Wie Pattern anwenden um Cipher zu nutzen Allgemeine Java-Themen 2
S Singleton Pattern mit Generics Allgemeine Java-Themen 4
M MVC Design Pattern - Verständniss Fragen Allgemeine Java-Themen 3
F Typüberprüfung in Superklasse - geeignetes Pattern? Allgemeine Java-Themen 11
M Java Pattern hilfe Allgemeine Java-Themen 6
N Observer Pattern Allgemeine Java-Themen 2
G Problem mit MVC-Pattern (Controller als anonyme Unterklasse) Allgemeine Java-Themen 2
F Design Pattern zur Realisierung von Mehrfachvererbung? Allgemeine Java-Themen 8
M Pattern aus Properties Allgemeine Java-Themen 3
I Composite Pattern für Ausgabe von Ausdruck Allgemeine Java-Themen 3
G mit Pattern strings filtern ein kleines problemchen ;) Allgemeine Java-Themen 2
M nach einem Pattern splitten Allgemeine Java-Themen 2
F Composite Pattern in Java? Allgemeine Java-Themen 1
G problem mit dem observer pattern Allgemeine Java-Themen 3
C Matcher/Pattern ersetzten für JDK 1.3 Allgemeine Java-Themen 2
M Pattern: Summary of regex constructs: Backslash Allgemeine Java-Themen 2
G Scanner und Abbruchbedingung/Pattern Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben