Ho avuto una ENORME istruzione switch/case
, che ho convertito per usare una funzione dispatch table
usando una lista di enum per l'indice.
Il mio collega (che sta facendo una revisione del codice su questo cambiamento) ha convenuto che dovrebbe essere suddiviso in diverse funzioni, ma c'è stata una modifica successiva che ha richiesto che alcuni parametri non fossero utilizzati in tutte le funzioni.
Il codice non è ancora stato finalizzato e il suo suggerimento è che al posto di dispatch table
, io uso un switch/case
che chiama le funzioni. La sua logica è che poiché non tutte le funzioni useranno tutti i parametri, che chiamare ogni singola funzione con firme leggermente diverse sarebbe meglio che usare una singola firma di funzione per tutte le singole funzioni.
Non sono troppo sfavorevole a questa idea, ma non sono davvero convinto che sia davvero un passo avanti. I parametri sono tutti i tipi di POD e solo gli ultimi due che vengono inoltrati non sono necessariamente utilizzati. Quindi non c'è un vero problema di prestazioni, anche se è stato chiamato molto, il che non è (richiede che l'utente preme un pulsante, rendendo il tempo di spedizione insignificante rispetto a).
Questo è approssimativamente il layout corrente che ho migrato:
enum FindWhere_e : int
{
FindInA = 0, // Find Where
FindInD = 1,
FindInC = 2,
FindInE = 3,
FindInH = 4,
FindInI = 5,
FindInJ = 6,
FindInK = 7,
FindInL = 8,
FindInM = 9,
FindInB = 10,
FindInN = 11,
FindInO = 12,
FindInP = 13,
FindInQ = 14,
FindInF = 15,
FindInR = 16,
FindInG = 17,
};
BOOL Paragraph::DoSearch(IParaIdxC ipara, int ichar, FindReplaceData *frData, BOOL firstpara, BOOL lastpara, int *nchanges, CDocEnvironment& docEnv, bool allowRedisplay, Section *pSection, CTextWindow* textWindow)
{
typedef decltype(&Paragraph::DoSearch) vtableElement_t;
static vtableElement_t const jumpTable[] =
{
&Paragraph::DoSearch_FindInA, // FindInA
&Paragraph::DoSearch_FindIn_D_C_B_O, // FindInD
&Paragraph::DoSearch_FindIn_D_C_B_O, // FindInC
&Paragraph::DoSearch_FindInE, // FindInE
&Paragraph::DoSearch_FindInH, // FindInH
&Paragraph::DoSearch_FindInI, // FindInI
&Paragraph::DoSearch_FindInJ, // FindInJ
&Paragraph::DoSearch_FindIn_K_L, // FindInK
&Paragraph::DoSearch_FindIn_K_L, // FindInL
&Paragraph::DoSearch_FindInM, // FindInM
&Paragraph::DoSearch_FindIn_D_C_B_O, // FindInB
&Paragraph::DoSearch_FindInN, // FindInN
&Paragraph::DoSearch_FindIn_D_C_B_O, // FindInO
&Paragraph::DoSearch_FindInP, // FindInP
&Paragraph::DoSearch_FindInQ, // FindInQ
&Paragraph::DoSearch_FindInF, // FindInF
&Paragraph::DoSearch_FindInR, // FindInR
&Paragraph::DoSearch_FindInG, // FindInG
};
// frData->Where is of type FindWhere_e
if ((unsigned int)(frData->Where) < std::extent<decltype(jumpTable)>::value)
{
return (this->*jumpTable[frData->Where])(ipara, ichar, frData, firstpara, lastpara, nchanges, docEnv, allowRedisplay, pSection, textWindow);
}
ASSERT(false); // Not handling an unregistered find type in the dispatch table.
return FALSE;
}
Quindi mi piacerebbe sapere se c'è qualche ragione per usarne uno sull'altro o se davvero non ha importanza dal punto di vista del design. Personalmente non trovo né più chiaro da leggere.