Я искал рефакторинг, который должен быть транзакционным кодом в модулях, где я могу применить шаблон автомата. Сначала я создал следующие классы:Java - Spring Framework - State Machine
public interface IExecutableState {
public void execute();
}
public class StateMachine {
// final:
private static final Logger LOGGER = Logger.getLogger(StateMachine.class);
// instance private:
private HashMap<String, State> validStates;
private State currentState;
// getters:
public HashMap<String, State> getValidStates() { return this.validStates; }
public State getCurrentState() { return this.currentState; }
// setters:
public void setValidStates(HashMap<String, State> validStates) {
// assign the stateMachine attribute to each State from this setter, so that Spring doesn't enter an infinite loop while constructing a Prototype scoped StateMachine.
for (State s : validStates.values()) {
// validate that the State is defined with implements IExecutableState
if (!(s instanceof IExecutableState)) {
LOGGER.error("State: " + s.toString() + " does not implement IExecutableState.");
throw new RuntimeException("State: " + s.toString() + " does not implement IExecutableState.");
}
LOGGER.trace("Setting stateMachine on State: " + s.toString() + " to: " + this.toString() + ".");
s.setStateMachine(this);
}
LOGGER.trace("Setting validStates: " + validStates.toString() + ".");
this.validStates = validStates;
}
public void setCurrentState(State currentState) {
if (!(currentState instanceof IExecutableState)) {
LOGGER.error("State: " + currentState.toString() + " does not implement IExecutableState.");
throw new RuntimeException("State: " + currentState.toString() + " does not implement IExecutableState.");
}
LOGGER.trace("Setting currentState to: " + currentState.toString() + ".");
this.currentState = currentState;
}
}
public class State {
private StateMachine stateMachine;
public StateMachine getStateMachine() { return this.stateMachine; }
public void setStateMacine(StateMachine stateMachine) { this.stateMachine = stateMachine; }
}
Все штаты будут выглядеть следующим образом: public class <StateName> extends State implements IExecutableState { ... }
.
Затем, с этой моделью, я хотел создать прототип скопированного весеннего боба, чтобы создать экземпляр stateMachine и присвоить ему все состояния.
Однако, посмотрев некоторые из вещей, доступных в Spring WebFlow, я начал видеть WebFlows, которые эмулируют поведение Machine Machine, которое я ищу, безупречно. И, таким образом, что позволяет визуальное представление каждого потока состояния, которое я создаю из XML.
Единственная проблема, которую я нахожу, - это WebFlows, предназначенные для веб-проектов/веб-приложений/веб-сайтов (в зависимости от того, что вы хотите классифицировать как). Я ищу что-то очень похожее на теги <view-state>
, которые вы получаете в Spring Webflow, но для приложения, которое работает в Spring-Core, Spring-Integration или Spring-Batch.
Вы намеренно желая сохранить набор состояний расширяемым, или они закрыты во время компиляции? – chrylis
@chrylis: Если вы спрашиваете, почему я использовал scope = prototype (в проекте, упомянутом в моем вопросе), это потому, что я хочу иметь несколько экземпляров объекта StateMachine в демона, который может запускать 1 экземпляр StateMachine для потока. Когда каждый StateMachine будет запускаться в своем первоначальном состоянии (какой-то dequeueState или waitUntilEventOccursState), тогда действовать на итоговую транзакцию, пропуская через каждое из состояний для этой транзакции и закрывая их, когда они будут выполнены. Концепция Spring Spring WebFlows отражает то, что я хочу, и поддерживает плагины, но для WebFlow. – anonymous
Причина, по которой я спрашиваю, заключается в том, что государственные машины со состояниями, известными во время компиляции, могут быть гораздо более чисто, легко и эффективно реализованы с помощью 'enum' вместо 'Map', и он может часто избегать необходимости в чем-либо сложном, машинный каркас. – chrylis