我正在为我的应用程序实现Java中的状态模式,并且需要很少的说明。实现状态模式
状态机有5个状态状态1到状态5. 总共有5个事件(Event1到Event5)导致状态转换。 并非所有事件都适用于所有州。如果事件不适用于该特定状态,应用程序将抛出异常。
当状态机得到初始化时,它从状态1开始。
以下是接口和上下文类。
/*
Interface defining the possible events in each state.
Each Implementer will handle event in a different manner.
*/
public interface State {
/*
Handlers for each event. Each Implementer will handle the vent in a different manner.
*/
public void handleEvent1(StateContext context);
public void handleEvent2(StateContext context);
public void handleEvent3(StateContext context);
public void handleEvent4(StateContext context);
public void handleEvent5(StateContext context);
// Method to enter state and do some action.
public void enter(StateContext context);
// Method to exit state and do some clean-up activity on exit .
public void exit(StateContext context);
}
/*
Context class which will handle the state change and delegate event to appropriate event handler of current state
*/
Class StateContext {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private State currentState = null;
StateContext() {
currentState = new State1();
}
//Handle event1 and pass it to the appropriate event handler for the current state.
public void handleEvent1() {
currentState.handleEvent1();
}
.
.
.
//Handle event5 and pass it to the appropriate event handler for the current state.
public void handleEvent5() {
currentState.handleEvent5();
}
// Method to change the state.
// This method will be called by each state when it needs to transit to a new state.
public void changeState(State newState) {
accquireLock();
currentState.exit();
currentState = newState;
currentState.enter();
}
// Release read lock and accquire write lock
public void accquireLock() {
lock.readLock().unlock()
lock.writeLock().lock();
}
// accquire readlock and release write lock
public void releaseLock() {
lock.readLock().lock()
lock.writeLock().unlock();
}
}
为了简单起见,我提供了只有一个状态的实现。
public class State1 implements State {
public void handleEvent1(StateContext context) {
//Hand1e Event 1
}
.
.
.
public void handleEvent5(StateContext context) {
//Handle Event 5
}
public void enter(StateContext context) {
//Release the lock here
context.releaseLock();
/*Here is my question. Is it a good java practice to expose accquire and release lock in Context object. And use the exposed method here to release lock.
*/
// Do some action on entering the state. This may take few seconds to finish
}
}
我想在进入状态后才能释放锁。我也不想锁定,直到enter()结束。如果我持有锁直到输入完成,我不能处理其他事件,并且它可能会超时。对于某些事件(它并不真正改变状态),我们需要读取状态并根据状态来处理它们或别理他们。如果我没有释放锁定,它们将不能被处理。另外在其他一些情况下,如果一个事件发生关闭(这个事件改变了状态),当enter()正在进行时,状态机将无法处理它。我必须立即关闭状态机,因为在关机事件发生后继续输入()不适合。
我的问题: 这是一个很好的java编程实践,将accquireLock和releaseLock公开为Context类中的API并在每个状态类中使用它们。
感谢, 阿伦
为什么在代码在你的'changeState()'方法中执行后你不调用'releaseLock()'?既然你在该方法开始时获得了锁,那么在它的最后释放锁似乎是一致的设计,不是吗? – Deactivator2
对于我的应用程序,如果我在enter()进行时收到关闭机器的关机事件,我不应该继续输入()。继续可能会导致不利影响,或者可能不会导致任何结果,除非浪费资源直到enter()结束。在某些情况下,输入可能需要超过5分钟,并发送很多请求。如果我继续请求,可能无法到达接收方,或者接收方可能会丢弃我的请求,我应该立即停止并转到初始状态(为此我需要锁定)。 – Arun
然后,你需要的是一种中断状态的'enter'方法的方法,它超越了你已有的任何锁定。将锁对象视为状态更改的块,但关闭事件优于任何状态更改事件,因此应该能够随时生效。 – Deactivator2