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