Rimozione delle dipendenze dal comportamento specifico della sottoclasse

1

Ho una classe Message che può contenere più tipi di payload (o talvolta nessun payload), ciascuno derivante da una comune classe Payload . Tuttavia, questo diventa problematico perché la classe Message vuole conoscere le sottoclassi Payload per vari motivi come:

  • Verifica dell'uguaglianza Message

    if (message parts besides the payload are equal) {
        switch(type) {
            case Payload::Type::RESPONSE:
                return *static_cast<ResponsePayload*>(payload.get())
                    == *static_cast<ResponsePayload*>(o.payload.get());
                break;
    
            case Payload::Type::SETUP:
                return *static_cast<SetupPayload*>(payload.get())
                    == *static_cast<SetupPayload*>(o.payload.get());
                break;
    
            ...
        }
    }
    
  • Deserializzazione (poiché i metodi di deserializzazione sono statici perché i carichi utili sono immutabili)

    switch(type) {
        case Payload::Type::RESPONSE:
            load = ResponsePayload::fromJSON(payloadValue);
            break;
    
        case Payload::Type::SETUP:
            load = SetupPayload::fromJSON(payloadValue);
            break;
    
        ...
    
        case Payload::Type::START:
        case Payload::Type::STOP:
        case ...:
            break; // Load stays null
    
        default:
            THROW(Exception, "Error in program logic: we forgot to parse some payload");
    }
    
  • Assicurati che Payload sia collegato a Message durante la costruzione:

    switch(type) {
        case Payload::Type::RESPONSE:
        case Payload::Type::SETUP:
        case ...:
            ENFORCE(IOException, payload != nullptr, "For this message type, a payload is required.");
            break;
    
        case Payload::Type::START:
        case Payload::Type::STOP:
        case ...:
            ENFORCE(IOException, payload == nullptr, "For this message type, the payload should be null");
            break;
    
        default:
            THROW(Exception, "Error in program logic: we forgot to handle some payload");
    }
    

I campanelli d'allarme stanno andando nella mia testa - questo viola SOLID come se non ci fosse domani e ovviamente non si adatta bene poiché devo aggiungere case dichiarazioni ogni volta che aggiungo un nuovo carico utile. C'è un approccio più pulito che potrei prendere?

    
posta Matt Kline 25.03.2014 - 21:25
fonte

1 risposta

3

I campanelli d'allarme dovrebbero spegnersi. Ma alcuni dei miei primi suggerimenti iniziali (il che significa che non ho avuto il tempo di trovare la soluzione migliore, solo una molto migliore di quella che hai).

1 - Perché esiste una classe separata per messaggi e payload, non sono la stessa cosa?

2 - Includere il controllo di uguaglianza nelle sottoclassi in cui prendono come parametro un istanza di payload. Le sottoclassi conoscono solo il loro tipo. Se passi un carico utile che non è del tipo giusto, la conversione del tipo fallirà e saprai che non sono uguali.

3 - Crea un factory Payload invece di creare tutti i vari tipi nella classe dei messaggi di base.

4 - Sottoclassi la classe Message se richiede che i parametri siano compilati correttamente.

    
risposta data 25.03.2014 - 22:19
fonte

Leggi altre domande sui tag