2009-10-09 10 views
3

J'ai ce cas de commutateur énorme avec des déclarations de cas de commutateur imbriqués dans ce que je me demandais si quelqu'un avait des idées sur la façon de nettoyer?c idées sur la réduction de cette fonction?

switch (datatype) { 
    case STR: 
    { 
     switch(operation) 
     { 
       case EQUALS: 
       { 
        /* perform str compare */ 
       } 
       case NOTEQUALS: 
       { 
       } 
       case LT: 
       { 
       } 
       case GT: 
       { 
       } 
       case GTE: 
       { 
       } 
       case LTE: 
       { 
       } 
       default: 
       break; 
     } 
     break; 
    } 
    case VER: 
    { 
     switch(operation) 
     { 
       case EQUALS: 
       { 
        /* perform version compare */ 
       } 
       case NOTEQUALS: 
       { 
       } 
       case LT: 
       { 
       } 
       case GT: 
       { 
       } 
       case GTE: 
       { 
       } 
       case LTE: 
       { 
       } 
       default: 
       break; 
     } 
     break; 
    } 
    case INT: 
    { 
     /* same */ 
    } 
    case FLOAT: 
    { 
     /* same */ 
    } 
    /* ... more types ... */ 
    /* ... .......... ... */ 
    default: 
     break; 
} 
+0

Puis-je demander pourquoi il est nécessaire de réduire cela? –

Répondre

11

Si les valeurs de l'opération sont contiguës, vous pouvez créer une table de pointeurs de fonction. En fait, vous pouvez créer une table 2D de pointeurs de fonction avec une fonction séparée pour gérer chaque combinaison opération/type. par exemple

// do some range checking on input params 
// invoke the handler 
handlers[datatype][operation](); 
+2

vous pouvez vouloir vérifier que 'datatype' et' operation' sont dans la plage correcte, sinon les mauvaises choses arriveront. – rmeador

+0

En fait, les compilateurs modernes convertissent automatiquement les gros commutateurs en variables (et vérifient bien sûr la portée) – hirschhornsalz

+3

@drhirsch: ce n'est pas une question de performance, c'est une question de code propre. – rmeador

0

Vous pouvez utiliser un grand nombre de pointeurs de fonction, puis appeler la fonction appropriée en fonction de l'indexation du pointeur de fonction correct dans le tableau.

5

Créez des tables (tableaux) avec des pointeurs sur les fonctions qui s'y trouvent. Vous pouvez ensuite rechercher func[STR][EQUALS] pour effectuer l'appel approprié. L'appel finirait par ressembler à ça ...

Func[datatype][operation](); 
2

Le cas NOTEQUALS peut toujours être écrit en termes de EQUALS cas; de manière similaire, GTE en termes de LT et LTE en termes de GE. Donc, faites le commutateur externe en termes de operation, et seulement trois de ces six cas devront activer le datatype.

+1

Pas toujours si vous considérez des commandes partielles. – liori

0

avez-vous envisagé de manière créative d'utiliser une série de pointeurs de fonction et de les stocker dans une structure?

-le correctement et vous pouvez imiter des objets et faire quelque chose comme cela:

bool someArbitraryFunction (dataType aDatatype, operations anOperation) 
{ 
someUnknownStruct.datatype = aDatatype; 
someUnknownStruct.operation = anOperation; 
return someUnknownStruct->doMath(1,2); 
} 

et vous pouvez mettre toutes les fonctions mathématiques nécessaires, énumérations et struct dans un fichier d'en-tête quelque part. Nettoie la "viande" du code, et rend le calcul portable (il suffit de l'importer où vous en avez besoin).

0

En supposant que votre cas peut tout retour d'une simple valeur booléenne, les six cas logiques peuvent être réécrites en termes de LT et equals, comme suit:

switch(operation) { 
    case EQUALS: 
    return isEquals(); 
    case NOTEQUALS: 
    return !isEquals(); 
    case LT: 
    return isLT(); 
    case GT: 
    return !isLT() && !isEquals(); 
    case GTE: 
    return !isLT(); 
    case LTE: 
    reutrn isLT() || isEquals(); 
    default: 
    break; 
} 

Cela ne ferait que vous avez besoin d'écrire la logique pour ISLT() et isEquals(), qui ferait le type de données de commutation si nécessaire. Cela élimine une quantité importante de duplication de code inutile, mais ne sacrifie pas beaucoup de lisibilité.

Ceci peut être combiné avec des pointeurs de fonction comme Stephen Doyle et rikh ont déjà suggéré, ce qui éliminerait complètement l'instruction switch().

Questions connexes