J'ai une méthode qui reçoit un objet et fait quelque chose en fonction du type d'objet qu'il détecte:
void receive(Object object) {
if (object instanceof ObjectTypeA) {
doSomethingA();
}
else {
if (object instanceof ObjectTypeB) {
doSomethingB();
}
else {
if (object instanceof ObjectTypeC) {
doSomethingC();
}
else {
if (object instanceof ObjectTypeD) {
doSomethingD();
}
else {
// etc...
}
}
}
}
}
Comment puis-je réduire la complexité cyclomatique? J'ai cherché autour mais je n'ai rien trouvé de trop utile.
Ne pouvez-vous pas tirer parti d'une approche orientée objet pour cela? Créer une interface qui a la méthode doSomething()
puis créer des sous-classes qui implémentent le comportement souhaité? Ensuite, appeler object.doSomething()
exécuterait le comportement approprié?
La complexité cyclomatique est une mesure basée sur la structure graphique du code. Plus précisément, il est basé sur le nombre de chemins possibles à travers le code; voir ici pour plus de détails. Bien qu'il existe une corrélation entre CC et ce qu'un programmeur typique considérerait comme la complexité du code, ce n'est pas la même chose. Par exemple:
CC ne tient pas compte de la sémantique du code; par exemple. ce que fait telle ou telle méthode appelée, ou les propriétés mathématiques d'un algorithme.
CC ne tient pas compte des modèles de conception et de codage. Donc, quelque chose que CC dit complexe peut très bien être simple pour quelqu'un qui comprend le modèle utilisé.
On pourrait dire que la relation entre CC et la complexité réelle du code est semblable à la relation entre IQ et l'intelligence réelle.
Ainsi, la complexité cyclomatique doit être traitée comme un indicateur de l'emplacement des parties complexes de votre code ... et non comme une véritable mesure de la complexité ou de la qualité du code. En effet, un code très complexe n'est pas nécessairement de mauvaise qualité. Souvent, la complexité est inhérente, et essayer de s'en débarrasser ne fait qu'empirer les choses.
Dans cet exemple particulier, la mesure CC élevée ne correspond pas à quelque chose qui causerait des difficultés à un programmeur typique. La meilleure réponse (OMI) est de laisser la méthode tranquille. Craquez-le comme un faux positif.
void receive(ObjectTypeA object) {
doSomethingA();
}
void receive(ObjectTypeB object) {
doSomethingB();
}
void receive(ObjectTypeC object) {
doSomethingC();
}
...
// Your final 'else' method
void receive(Object object) {
doSomethingZ();
}