1

, что хорошие шаблоны проектирования, чтобы решить, какой метод для вызова на сервере на основе текущего состояния соединения?Design Pattern, обрабатывать сообщения, основанные на состоянии

Предположим, что сервер получает сообщения, и в зависимости от текущего состояния он должен решить, что делать.

Очевидная идея будет использовать перечисление:

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