Je lisais cet article et je me demandais: supprimons-nous toutes les instructions de commutateur en les remplaçant par un dictionnaire ou une usine afin qu'il n'y ait aucune instruction de commutateur dans mes projets.
Quelque chose ne s'additionnait pas vraiment.
La question est de savoir si les instructions switch ont une utilité réelle ou allons-nous les remplacer par un dictionnaire ou une méthode d'usine (en utilisant une méthode d'usine, bien sûr, il y aura une utilisation minimale des instructions switch pour créer les objets en utilisant l'usine ... mais c'est à peu près tout).
refactoring
switch-statement
Kanini
la source
la source
Réponses:
Les
switch
déclarations et le polymorphisme ont tous deux leur utilité. Notez cependant qu'une troisième option existe également (dans les langages qui prennent en charge les pointeurs de fonction / lambdas et les fonctions d'ordre supérieur): mapper les identificateurs en question aux fonctions de gestionnaire. Ceci est disponible par exemple en C qui n'est pas un langage OO, et C # qui est *, mais pas (encore) en Java qui est aussi OO *.Dans certains langages procéduraux (n'ayant ni polymorphisme ni fonctions d'ordre supérieur)
switch
/ lesif-else
déclarations étaient le seul moyen de résoudre une classe de problèmes. De nombreux développeurs, habitués à cette façon de penser, ont continué à utiliserswitch
même dans les langages OO, où le polymorphisme est souvent une meilleure solution. C'est pourquoi il est souvent recommandé d'éviter lesswitch
déclarations / refactor en faveur du polymorphisme.Quoi qu'il en soit, la meilleure solution dépend toujours de la casse. La question est: quelle option vous donne un code plus propre, plus concis et plus facile à gérer à long terme?
Les instructions de commutation peuvent souvent devenir lourdes, avec des dizaines de cas, ce qui rend leur maintenance difficile. Comme vous devez les conserver dans une seule fonction, cette fonction peut devenir énorme. Si tel est le cas, vous devriez envisager une refactorisation vers une solution basée sur une carte et / ou polymorphe.
Si le même
switch
commence à apparaître à plusieurs endroits, le polymorphisme est probablement la meilleure option pour unifier tous ces cas et simplifier le code. Surtout si d'autres cas devraient être ajoutés à l'avenir; plus vous avez besoin de mises à jour à chaque fois, plus il y a de possibilités d'erreurs. Cependant, souvent les gestionnaires de cas individuels sont si simples, ou il y en a tellement, ou ils sont tellement interdépendants, que les refactoriser dans une hiérarchie de classes polymorphes complète est exagéré, ou entraîne beaucoup de code dupliqué et / ou emmêlé, difficile de maintenir la hiérarchie des classes. Dans ce cas, il peut être plus simple d'utiliser à la place des fonctions / lambdas (si votre langue le permet).Cependant, si vous en avez un
switch
dans un seul endroit, avec seulement quelques cas faisant quelque chose de simple, ce pourrait bien être la meilleure solution pour le laisser tel quel.* J'utilise le terme "OO" de manière lâche ici; Je ne suis pas intéressé par les débats conceptuels sur ce qui est «réel» ou «pur» OO.
la source
C'est là que je redeviens dinosaure ...
Les instructions Switch ne sont pas mauvaises en soi, c'est l'utilisation qui en est faite qui est en cause.
La plus évidente est la "même" instruction de commutateur répétée maintes et maintes fois dans votre code qui est mauvaise (là-bas, fait cela, ferait tout son possible pour ne pas recommencer) - et c'est ce dernier cas que vous pourrez peut-être traiter avec l'utilisation du polymorphisme. Il y a généralement quelque chose d'assez horrible dans les cas imbriqués aussi (j'avais l'habitude d'avoir un monstre absolu - je ne sais pas vraiment comment je le gère maintenant autre que "mieux").
Dictionnaire comme commutateur Je trouve plus difficile - fondamentalement oui si votre commutateur couvre 100% des cas, mais là où vous voulez avoir des cas par défaut ou sans action, cela commence à devenir un peu plus intéressant.
Je pense que c'est une question d'éviter la répétition et de nous assurer que nous composons nos graphiques d'objets aux bons endroits.
Mais il y a aussi l'argument de compréhension (maintenabilité) et cela coupe dans les deux sens - une fois que vous comprenez comment tout cela fonctionne (le modèle et l'application dans laquelle il est implémenté), c'est facile ... mais si vous arrivez à une seule ligne de code où vous devez ajouter quelque chose de nouveau, vous devez ensuite sauter partout pour déterminer ce que vous devez ajouter / modifier.
Pour autant que nos environnements de développement soient massivement capables, je pense toujours qu'il est souhaitable de pouvoir comprendre le code (comme s'il était) imprimé sur du papier - pouvez-vous suivre le code avec votre doigt? J'accepte qu'en fait non, avec beaucoup de bonnes pratiques aujourd'hui, vous ne pouvez pas et pour de bonnes raisons, mais cela signifie qu'il est plus difficile de se familiariser avec le code (ou peut-être que je suis juste vieux ...)
la source
Switch-statement vs subtype-polymorphism est un vieux problème et est souvent mentionné dans la communauté FP dans les discussions sur le problème d'expression .
Fondamentalement, nous avons des types (classes) et des fonctions (méthodes). Comment codons-nous des choses pour qu'il soit facile d'ajouter de nouveaux types ou de nouvelles méthodes?
Si vous programmez dans le style OO, il est difficile d'ajouter une nouvelle méthode (car cela signifierait une refactorisation de toutes les classes existantes), mais il est très facile d'ajouter de nouvelles classes qui utilisent les mêmes méthodes qu'auparavant.
D'un autre côté, si vous utilisez une instruction switch (ou son équivalent OO, le modèle Observer), il est très facile d'ajouter de nouvelles fonctions, mais il est difficile d'ajouter de nouveaux cas / classes.
Il n'est pas facile d'avoir une bonne extensibilité dans les deux sens, donc lors de l'écriture de votre code, déterminez s'il faut utiliser le polymorphisme ou basculer les instructions en fonction de la direction dans laquelle vous êtes le plus susceptible d'étendre ce dernier.
la source
Non. De tels absolus sont rarement une bonne idée.
À de nombreux endroits, une répartition dictionnaire / recherche / usine / polymorphe fournira une meilleure conception qu'une instruction switch, mais vous devez toujours remplir le dictionnaire. Dans certains cas, cela obscurcira ce qui se passe réellement et le simple fait d'avoir l'instruction switch en ligne est plus lisible et maintenable.
la source
Étant donné que cela est indépendant du langage, le code de transition fonctionne mieux avec les
switch
instructions:Équivalent à
if
, avec un cas par défaut très gênant. Et gardez à l'esprit que plus il y a de retombées, plus la liste de conditions s'allonge:(Cependant, compte tenu de ce que disent certaines des autres réponses, j'ai l'impression d'avoir raté le point de la question ...)
la source
switch
comme étant au même niveau que agoto
. Si l'algorithme à exécuter nécessite des flux de contrôle qui correspondent à des constructions de programmation structurées, il faut utiliser de telles constructions, mais si l'algorithme ne correspond pas à de telles constructions, l'utilisationgoto
peut être meilleure que d'essayer d'ajouter des indicateurs ou une autre logique de contrôle pour s'adapter à d'autres structures de contrôle .Les instructions Switch car la différenciation des cas ont une réelle utilité. Les langages de programmation fonctionnels utilisent quelque chose appelé correspondance de modèle qui vous permet de définir des fonctions différemment selon l'entrée. Cependant, dans les langages orientés objet, le même objectif peut être atteint plus élégamment en utilisant le polymorphisme. Vous appelez simplement la méthode et selon le type réel de l'objet, l'implémentation correspondante de la méthode sera exécutée. C'est la raison derrière l'idée, que les instructions switch sont une odeur de code. Cependant, même dans les langages OO, vous pourriez les trouver utiles pour implémenter le modèle d'usine abstrait.
tl; dr - ils sont utiles, mais vous pouvez souvent faire mieux.
la source