1

根据当前连接状态决定在服务器上调用什么方法的良好设计模式是什么?设计模式,基于状态处理消息

假设服务器接收到消息 ,并根据当前状态决定要做什么。

明显的想法是使用一个枚举:

enum State{LISTEN, SYN_REC, ESTABLISHED}; 
State state = State.LISTEN; 

void msgReceived(Object msg){ 
if(state==State.LISTEN){ /* … */ } 
    else if(state == State.SYN_REC){ /* … */ } 
    else if(state == State.ESTABLISHED){ /* … */ } 
} 

这是非常丑陋的代码。

接下来的想法是使枚举提供一个手柄方法:

enum State { 
    LISTEN{ public void handle(Object msg){ /* … */ } }, 
    SYN_REC{ public void handle(Object msg){ /* … */ } }, 
    ESTABLISHED{ public void handle(Object msg){ /* … */ } }; 
    public abstract void handle(Object msg); 
}; 

State state = State.LISTEN; 

void msgReceived(Object msg){ 
    state.handle(msg); 
} 

看起来比第一个想法干净多了,但也存在问题。枚举不能访问在服务器级别定义的属性和方法。人们必须通过处理所需的所有变量。

有没有更干净的方法来做到这一点,我想避免为此定义额外的公共类?

+0

[策略模式](http://en.wikipedia.org/wiki/Strategy_pattern) –

+0

它更多的[ADT](http://en.wikipedia.org/wiki/Abstract_data_type)那么它是* pattern *,但我会使用[FSM](http://en.wikipedia.org/wiki/Finite-state_machine)。 –

回答

3

这绝对是一个Strategy pattern。您可以实现这一点的很酷的方式是将它与state pattern配对为枚举。

所以,你的例子是在正确的轨道上。在你的枚举中声明一个抽象方法,然后让每个状态实现它。返回结果是新的状态。

而且,是的,因为直到通话时间你才知道,所以你必须在通话中传递所有这些信息。

Example of abstract enums