Maszyna stanowa – zagada projektowa
Ciekawa, moim zdaniem, łamigłówka i zagadka projektowa. Niby każdy wie, ale nigdzie nie znalazłem ładnego wytłumaczenia.
Mamy sobie prostą maszynę stanową w postaci enuma wzbogaconego o metodę sprawdzającą dopuszczalność przejścia:
Listing 1. enum State, czyli maszyna stanowa
public enum State {
A, B, C, D;
private List<State> validChanage;
static {
A.validChanage = Arrays.asList(B);
B.validChanage = Arrays.asList(C);
C.validChanage = Arrays.asList(A, D);
D.validChanage = Arrays.asList(D);
}
public boolean couldChange(State newState) {
return validChanage.contains(newState);
}
}
Takie toto prymitywne, że aż żal patrzeć… do tego mamy sobie obiekt, który wykorzystuje tego enuma do zarządzania własnym stanem:
listing 2. klasa StateObject
public class StateObject {
private State currentState;
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
if (this.currentState != null
&& !this.currentState.couldChange(currentState)) {
throw new IllegalStateException(
String.format("Can not change from %s to %s",
this.currentState, currentState));
}
this.currentState = currentState;
}
}
Teraz zagadka:
- Czy dodanie logiki do settera jest ok? Przy czym nie jest istotne co robi logika.
- Kiedy takie rozwiązanie jest poprawne, a kiedy nie?
- Jeżeli nie to dlaczego?
Kod jest dostępny na licencji MIT. Jednak niektóre rozwiązania mogą być objęte inną licencją. W takim przypadku jest, to zaznaczone. Artykuły są dostępne na licencji CC-BY.
Jeżeli spodobał ci się ten wpis, to podziel się nim z innymi lub wesprzyj autora.