sta scendendo sempre male?

7

Nella mia azienda, disponiamo di molti "servizi" diversi che funzionano in parallelo e inviano messaggi tra loro utilizzando un sistema di messaggistica comune. Tutti gli oggetti messaggio provengono da un oggetto generico comune che abbiamo definito per la messaggistica. Quando un servizio riceve un messaggio, la prima cosa che deve fare è ritrasmettere l'oggetto al tipo derivato in modo che possa estrarre i dati necessari.

Ho letto su Internet che non dovresti downcast un puntatore a oggetti di base su un puntatore a oggetti derivati e che doverlo fare è spesso un segno di cattiva progettazione. Sono d'accordo con questo sentimento per la maggior parte dei casi. E posso immaginare diversi progetti per l'oggetto messaggio generico che non richiederebbero down-casting. Ma non vedo alcuna grande ragione per gestire questa situazione in modo diverso.

Quindi la mia domanda complessiva è: il down-casting è sempre una brutta cosa? Ci sono situazioni in cui il down-casting è necessario o accettabile?

    
posta c.hughes 11.03.2013 - 17:13
fonte

3 risposte

9

Downcasting di un puntatore e creazione di un payload generico in un oggetto specifico sono due cose diverse.

L'API del sistema di messaggistica comune dovrebbe avere un set di funzioni per restituire l'oggetto esatto che desideri, in modo da non essere costantemente downcast nel codice dell'applicazione (che è più soggetto a errori).

In pratica stai parlando di passare oggetti usando XML o JSON o qualche altro formato di scambio di dati. Parlare di downcasting non è necessario perché dovrebbe già essere gestito dall'API del sistema di messaggistica in comune poiché sai esattamente quali tipi di oggetti vengono passati.

Suppongo che l'API di sistema assomigli a questa:

GeneralObject* getObject(Message *message);

Dovrebbe assomigliare a questo:

GeneralObject* _getObject(Message *message); // the _ is just to indicate this is a private function that shouldn't be used outside of this module

// these raise exceptions if the object doesn't exist or return null or whatever
Person* getPerson(Message *message);
Place* getPlace(Message *message);

Mai nel tuo codice userai la funzione generica che restituisce la classe base, userai sempre il codice che restituisce le classi derivate e lasci che l'API gestisca o rilevi errori se non può downcast.

In questo caso, il downcasting non è in grado di analizzare o de-serializzare un oggetto.

La libreria protobuf di Google ha un esempio di ciò di cui sto parlando

    
risposta data 11.03.2013 - 17:35
fonte
4

Ovviamente, se fosse sempre una cosa negativa, non sarebbe necessario che il linguaggio supportasse l'operazione. La serializzazione / messaggistica è una grande eccezione, perché il downcast generalmente semplifica enormemente il codice, anche se dovresti davvero creare il cast nell'oggetto di coda dei messaggi. I modelli sono spesso utili in questo caso.

L'altra situazione che ho visto dove i downcast sono spesso inevitabili è in equals (Object obj) sovrascrive, poiché quella firma specifica fa parte di un'interfaccia ampiamente utilizzata e pubblicata.

    
risposta data 11.03.2013 - 17:52
fonte
2

Sì, il downcasting è sempre negativo. Sì, occasionalmente ti imbatterai in scenari (come i costrutti di messaggistica) in cui le alternative sono peggiori.

E ovviamente "peggio" è soggettivo. In alcuni scenari, la fragilità del down casting è inaccettabile. In altri, la semplicità del design o della leggibilità potrebbe avere una priorità più alta. Come ogni altra decisione sul design, è un compromesso che dovrai valutare per la tua situazione.

    
risposta data 11.03.2013 - 17:32
fonte

Leggi altre domande sui tag