Come dovrei codificare un modello di osservatore di più tipi?

0

Abbiamo alcuni stati, a seconda di una finestra attualmente attiva:

public enum LoginState{
    NONE,
    LOGGIN_IN,
    LOGIN_SUCCESS,
    LOGIN_FAILED
}

public enum LobbyState{
    NONE,
    FINDING_MATCH,
    FOUND_MATCH
}

Devo informare gli ascoltatori in merito a cambiamenti di stato tramite qualcosa come:

UIManager.Instance.Notify(LobbyState.FINDING_MATCH)

quindi gli abbonati vengono avvisati della modifica. Il problema con questo approccio è che ho più tipi di stato come LoginState , LobbyState , MatchState e devo essere in grado di iscriversi solo a quelli specifici.

Ad esempio: devo ascoltare login changes in lobby , ma non ho bisogno di ascoltare login window per lobby changes .

La prima cosa che mi è venuta in mente è che ho creato un Event System globale in cui registro i listener di stato e invoco le modifiche ai sottoscrittori.

Ad esempio:

public interface StateListener<T>{
    void OnStateChanged(T state);
}

che può essere utilizzato con diversi tipi di stato come:

class Lobby : StateListener<MatchState>, StateListener<ProfileState> {

    public Lobby(){
        EventSystem.Register(this); // here's the issue no. 1
        EventSystem.Register<MatchState>(this); // or this
        EventSystem.Register<ProfileState>(this); // or this
        ...
    }

    void OnStateChanged(MatchState state){
        switch(state) { // do things }
    }
    void OnStateChanged(ProfileState state){
        switch(state) { // do things }
    }

}

Il problema con questo approccio è che diventa un disastro quando registro diversi listener come puoi vedere nel costruttore della classe sopra. Inoltre, devo fornire un tipo generico due volte (nella dichiarazione della classe e nel costruttore).

Potrei creare 10 diversi contenitori per tutti i tipi di stato come:

List<StateListener<MatchState>> matchStateListeners;
List<StateListener<LoginState>> loginStateListeners;
...

public void RegisterListener(StateListener<MatchState> listener){
 // add
}

public void RegisterListener(StateListener<LoginState> listener){
 // add
}
...

Ma poi, diventa un vero casino.

Esiste un approccio migliore per ottenere qualcosa di simile?

    
posta Spectre 25.07.2017 - 19:19
fonte

0 risposte

Leggi altre domande sui tag