70 votes

Programmation sans condition (en fait, sans conditionnel)

J'ai un collègue qui m'a dit qu'il avait travaillé dans une entreprise qui avait pour politique de ne jamais avoir de conditionnelles (instructions "if" et "switch") dans le code et qu'ils laissaient toutes les décisions dans le code être prises en utilisant le polymorphisme et (je suppose) d'autres principes OO.

I en quelque sorte Je comprends le raisonnement qui sous-tend ce concept, à savoir que le code est plus rationnel et plus facile à mettre à jour, mais je cherche une explication plus approfondie de ce concept. Ou peut-être cela fait-il partie d'une approche de conception plus générale.

Si quelqu'un a des ressources à ce sujet ou est prêt à expliquer ou même à avoir d'autres termes liés à ce sujet que je peux utiliser pour trouver plus de réponses, je vous en serais très reconnaissant.

J'ai trouvé une question sur le SO c'était un peu lié mais je ne suis pas familier avec le C++ donc je ne comprends pas trop les réponses.

(Je ne suis pas un gourou de l'OO, mais je peux me débrouiller).

Je suis plus compétent en PHP, et ensuite en Python, donc je préfère les informations qui utilisent ces langages.

Mise à jour : je demanderai à mon collègue plus d'informations sur ce qu'il voulait dire exactement.

Mise à jour 2015 : après quelques années supplémentaires d'expérience en programmation, je vois maintenant que le but de cette politique était probablement d'empêcher les programmeurs d'ajouter des fonctionnalités de manière désordonnée en ajoutant simplement des conditionnels (instructions if) à certains endroits. Une meilleure façon d'étendre un logiciel est d'utiliser la fonction "Principe d'ouverture/fermeture" où les logiciels sont étendus en utilisant l'héritage et le polymorphisme. Je doute fortement que la politique ait été super stricte sur tous les conditionnels car il est assez difficile de s'en passer complètement.

16 votes

Quelle est cette entreprise dont parle votre collègue ? Je demande pour pouvoir les éviter. Les instructions de contrôle de flux sont fondamentales pour la programmation. Si je ne peux même pas utiliser les outils les plus basiques lorsqu'ils sont appropriés pour faire le travail, qu'est-ce que je ne peux pas utiliser d'autre ? Oui, il est vrai que vous pouvez abuser if mais c'est vrai pour tout le reste.

16 votes

@In silico - Les déclarations de contrôle de flux sont fondamentales pour procédure la programmation. Le polymorphisme est fondamental pour la programmation orientée objet. Cela dit, la plupart d'entre nous utilisent les deux paradigmes.

6 votes

@TrueWill : Le contrôle du flux est fondamental pour la programmation impérative, et la POO est autant basée sur la programmation impérative que sur la programmation procédurale. Même lorsque vous faites de la POO "pure", vous avez toujours la même chose enveloppée dans une robe légèrement plus POO ( condition ifTrue tel que Smalltalk le fait, a essentiellement le même effet et la même signification que if condition ). Et vous ont d'utiliser un certain contrôle de flux sur le polymorphisme, à moins que vous ne vouliez envelopper tout (comme la régularité d'un nombre entier) en objets dédiés.

66voto

TrueWill Points 14855

Il existe des ressources sur le site Campagne anti-IF site, comme cet article .

Je crois que c'est une question de degré. Les conditionnels ne sont pas toujours mauvais, mais ils peuvent être (et sont souvent) utilisés de manière abusive.

Réflexions supplémentaires (un jour plus tard)

Refactoring : Améliorer la conception du code existant est une bonne référence sur ce sujet (et bien d'autres). Il couvre Remplacer le conditionnel par le polymorphisme . Il y en a aussi un nouveau, Remplacer Conditionnel par Visiteur sur le site web.

J'apprécie la simplicité et responsabilité unique en supprimant tous les if les déclarations. Ces trois objectifs coïncident souvent. Les outils d'analyse statique qui prennent en charge le complexité cyclomatique La métrique permet de repérer rapidement le code contenant des conditionnels imbriqués ou en série. Le site if peuvent subsister après la refactorisation, mais pourraient être divisées en méthodes plus petites et/ou en classes multiples.

Mise à jour : Michael Feathers a écrit un article sur Programmation inconditionnelle .

C'est un sujet populaire : Phil Haack sur La mort de l'instruction IF !

4 votes

Je pense qu'il est également important d'inclure cette vidéo de Google Tech Talks qui parle de ce principe : youtube.com/watch?v=4F72VULWFvc

16voto

Niels Bom Points 1955

Après quelques années de programmation, je reviens à ma propre question, dont je comprends maintenant un peu mieux le contexte.

Il y a un bon exposé de Sandi Metz où elle refactorise une boule très poilue de déclarations if en quelque chose de beaucoup moins poilu : https://www.youtube.com/watch?v=8bZh5LMaSmE

7voto

Heisenbug Points 20496

J'ai un collègue qui m'a dit qu'il a travaillé une fois pour une entreprise qui avait pour politique de ne jamais utiliser de conditionnel ("je"). [ ] [ ] [ ]

Je pense que votre collègue a mal compris quelque chose ou a utilisé les mauvais mots pour l'expliquer. Et vous ne pouvez pas complètement éviter les déclarations conditionnelles.

Il y a une chose à dire : la prolifération des instructions if dans la POO peut être un symptôme de mauvaise programmation. Quelques exemples :

N'utilisez pas if pour vérifier la valeur de retour de la fonction comme dans l'ancienne programmation en C :

int ret = some_func();
if (ret != null)
   //do something

C'était typique du code C, mais avec la POO, vous devez utiliser les exceptions :

try{
    do_something();
}catch(Exception e){
    e.printStackTrace(); //why I was not able to do something
    handle(e); //there is something else I could do to handle the occurred error
}

Parfois, si la prolifération des déclarations est liée à une mauvaise conception. Prenons l'exemple suivant en Java :

BaseClass base;
if (base instanceof DerivedClassOneFromBase){
    DerivedClassOneFromBase d = (DerivedClassOneFromBase)base;
    d.methodOne();
}else if (base instanceof DerivedClassOneFromBase){
    DerivedClassTwoFromBase d = (DerivedClassTwoFromBase)base;
    d.methodTwo();
}

Il s'agit d'un autre exemple de mauvaises instructions "si", probablement liées à une mauvaise conception. Si les deux objets dérivés avaient une méthode commune définie dans leur classe de base BaseClass, vous auriez pu appeler cette méthode au lieu de vérifier leur type concret et de les couler :

base.commonMethod();

1 votes

Je suis d'accord que trop de ifs dans une application est une mauvaise symétrie ! Mais utiliser try catch comme structure de décision de flux est encore pire, 1. vous utilisez if/else de la même manière 2. c'est TROP LENT (expérience personnelle !!!). ps ; Je ne dis pas que votre code ci-dessus est bon ou mauvais car il est isolé de tout contexte.

0 votes

@Renato - Comme vous le dites, c'est une question de contexte. Microsoft recommande d'utiliser les exceptions pour signaler les erreurs/échecs, par opposition aux valeurs de retour. Il y a un chapitre sur ce sujet dans Directives de conception du cadre .

5 votes

@Renato Gama : oui les exceptions sont légèrement plus lentes, mais le fait est que ce sont des exceptions. Elles ne sont pas censées contrôler la structure de décision du flux, mais gérer les erreurs occasionnelles.

7voto

Mike Points 3808

J'ai lu l'article que vous avez cité et il semble qu'ils parlaient surtout de la suppression des conditionnels. au sein d'une classe à ne pas confondre avec tout le code en général. L'idée est que si vous devez vérifier l'état d'un objet (à l'aide d'une condition) pour déterminer s'il possède une certaine fonctionnalité, alors vous avez en réalité deux objets (un qui supporte la fonctionnalité et un qui ne la supporte pas) et vous devez les définir comme deux classes liées.

6voto

BobTurbo Points 192

Parfois, les conditions à l'intérieur des méthodes sont néfastes, car elles indiquent que vous exécutez plusieurs fonctions ou plusieurs types de méthodes dans une seule méthode.

Si vous avez une classe appelée Automobile et des sous-classes telles que Car et Bike, et une méthode telle que :

drive(Automobile a)
   if (a.isCar)
      // do stuff
   else if (a.isBike)
      // do stuff

vous faites très probablement quelque chose de mal. Même si ce n'est pas un interrupteur basé sur le type, il peut souvent être erroné. Si la méthode exécute plusieurs fonctions en fonction d'une variable, elle essaie souvent de faire plus d'une chose et devrait probablement être séparée en plusieurs méthodes.

Par exemple :

save(Car c)
   if (c is new)
      // do some stuff
   else if (c is old)
      // do some stuff

pourrait éventuellement être divisé en deux parties, à savoir la sauvegarde et la mise à jour, car il s'agit de deux fonctions différentes. Mais cela dépend.

Il serait toutefois stupide d'interdire complètement les instructions "si", car elles ont de nombreux cas d'utilisation valables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X