Les paramètres facultatifs sont-ils utiles ou gênent-ils la maintenance de l'application? [fermé]

15

Comme indiqué dans le titre, les paramètres facultatifs, tels que ceux utilisés en C #, sont-ils utiles ou constituent-ils un obstacle à la maintenance des applications et doivent-ils être évités car ils peuvent rendre le code plus difficile à comprendre?

rjzii
la source
3
Avertissement: toute fonctionnalité linguistique entre de mauvaises mains peut être utilisée de manière abusive. Si une langue l'implémente de manière intelligente, et que cette fonctionnalité de langue ne chevauche pas trop avec une fonctionnalité de langue existante de manière terne, alors elles sont très bien, en fait très utiles. Python a un bon paramétrage / décompactage de paramètres et d'autres "astuces" de paramètres (astuces dans un bon sens, pas dans le sens de Perl).
Job du
Essayez d'écrire une application en C # qui s'interface avec Excel sans utiliser de paramètres facultatifs. Cela devrait répondre à votre question hors de tout doute raisonnable.
Dunk

Réponses:

22

D'après mon expérience, les paramètres facultatifs ont été une bonne chose. Je ne les ai jamais trouvés déroutants (du moins pas plus déroutants que la fonction réelle), car je peux toujours obtenir les valeurs par défaut et savoir ce qui est appelé.

Une utilisation pour eux est quand je dois ajouter un autre paramètre à une fonction qui est déjà généralement utilisée, ou du moins dans l'interface publique. Sans eux, je devrais refaire la fonction d'origine pour en appeler une qui a un autre argument, et qui peut devenir très vieux si je finis par ajouter des arguments plus d'une fois.

David Thornley
la source
1
+1 Et c'est utile avec des méthodes surchargées qui ajoutent un argument comme new Circle(size, color, filled, ellipseProportions)sizeet colorsont obligatoires et les autres sont par défaut.
Michael K
15

En général, si vous avez souvent besoin de nombreux paramètres / optionnels, vos fonctions en font trop et doivent être décomposées. Vous violez probablement le SRP (principe de responsabilité unique).

Recherchez les paramètres qui peuvent être regroupés, par exemple (x et y, deviennent un point).

Ces paramètres optionnels sont-ils des drapeaux par défaut? Si vous utilisez des indicateurs, la fonction doit être divisée.

Cela ne veut pas dire que vous ne devriez jamais avoir de paramètres facultatifs, mais en général, plus d'un ou deux paramètres suggèrent une odeur de code.

Il pourrait également être un indice que la fonction, devrait en fait être une classe, avec les paramètres facultatifs modifiés en propriétés, et les paramètres requis partie du constructeur.

CaffGeek
la source
1
+1 pour avoir fait attention. N'importe quelle fonctionnalité, aussi bonne soit-elle, peut être utilisée à mauvais escient.
Michael K
3
C'est un excellent conseil pour produire du code ravioli sur-conçu où les utilisateurs de votre API doivent utiliser au moins 6 classes et 15 fonctions pour rendre la chose la plus simple possible.
dsimcha
1
@dsimcha, comment obtenez-vous cela de ce que j'ai écrit? Sensationnel. S'il vous plaît, expliquez? Ce serait également une mauvaise conception d'avoir une "super fonction" qui est ce que vous obtenez lorsque vous avez beaucoup de paramètres facultatifs. Découvrez les principes de conception SOLIDE et écrivez du code testable. Utiliser de préférence TDD. Revenez ensuite et essayez de m'expliquer que la réduction des paramètres dans les fonctions est une mauvaise chose.
CaffGeek du
1
Le code testable est agréable, mais il en est de même pour une API propre et utilisable qui n'est pas trop fine ni verbeuse et qui ne fait pas passer les classes dans une situation où une fonction est l'abstraction appropriée. Je crois au principe de responsabilité unique avec des responsabilités définies à un haut niveau d'abstraction. Si les responsabilités sont définies à un niveau trop bas, les unités individuelles deviennent trop simplifiées de sorte que leurs interactions sont trop complexes.
dsimcha
1
@dsimcha, vous manquez le point. Les unités individuelles doivent rester des unités individuelles et ne pas être regroupées dans une seule fonction. Cela ne signifie pas non plus que ce sont toutes des fonctions accessibles au public. Votre API est la passerelle vers le code et doit être claire et concise. Une fonction avec plusieurs paramètres facultatifs n'est ni propre, ni concise. Cependant, la surcharge d'une seule fonction avec des paramètres logiques est beaucoup plus claire. Par exemple, il existe des fonctions dans de nombreuses API où, deux paramètres sont facultatifs, mais l'un ou l'autre est requis. Qu'est-ce qui est clair à ce sujet lorsque les deux sont marqués comme facultatifs?
CaffGeek,
4

Les paramètres optionnels sont très bien

Généralement, la justification est soit a) vous savez que vous avez beaucoup d'arguments possibles pour votre méthode, mais vous ne voulez pas surcharger de peur de surcharger votre API, ou b) lorsque vous ne connaissez pas tous les arguments possibles, mais vous ne voulez pas forcer votre utilisateur à fournir un tableau. Dans chaque cas, les paramètres facultatifs viennent à la rescousse d'une manière soignée et élégante.

Voici quelques exemples:

1. Vous voulez éviter la surcharge et ne souhaitez pas spécifier de tableau

Jetez un œil à printf () de C, Perl, Java etc. C'est un excellent exemple de la puissance des paramètres optionnels.

Par exemple:

printf("I want %d %s %s",1,"chocolate","biccies");

printf("I want %d banana",1);

Pas de surcharge, pas de tableaux, simple et intuitif (une fois que vous avez saisi les codes de format de chaîne standard). Certains IDE vous diront même si votre chaîne de format ne correspond pas à vos paramètres facultatifs.

2. Vous souhaitez autoriser l'utilisation des valeurs par défaut et les cacher à l'utilisateur de la méthode

sendEmail ("[email protected]");

La méthode sendEmail détecte que diverses valeurs essentielles sont manquantes et les remplit en utilisant des valeurs par défaut définies (sujet, corps, cc, bcc, etc.). L'API est maintenue propre, mais flexible.

Une note sur trop de paramètres

Cependant, comme d'autres l'ont dit, avoir trop de paramètres obligatoires pour une méthode indique que vous avez probablement quelque chose de mal avec votre conception. Cela est particulièrement vrai s'ils partagent le même type car ils peuvent être modifiés par le développeur par accident, ce qui conduit à des résultats étranges lors de l'exécution:

String myMethod(String x, String y, String z, String a, int b, String c, int d) {}

est un candidat idéal pour le refactoring Introduce Object Parameter pour créer

String myMethod(ParameterObject po) {}

class ParameterObject {
  // Left as public for clarity
  public String x;
  public String y;
  ... etc

}

À son tour, cela peut conduire à une meilleure conception basée sur un modèle d'usine avec une spécification fournie comme objet de paramètre.

Gary Rowe
la source
1
Les fonctions de formatage de chaînes comme printf sont l'exception à la règle, on pourrait dire que même si elles utilisent une liste illimitée de paramètres facultatifs, cela ressemble plus à l'argument est un tableau qu'à des paramètres facultatifs, malgré la façon dont il est implémenté.
CaffGeek
@Chad J'ai ajusté ma réponse pour mieux différencier les paramètres facultatifs et le moment où ils passent en odeur de code (comme vous l'avez mentionné dans votre réponse).
Gary Rowe
@Gary Rowe, trop de paramètres facultatifs sont également mauvais dans la plupart des cas.
CaffGeek
@Chad Je suis d'accord, mais la plupart des langues ne fournissent pas de moyen de spécifier une limite sur le nombre d'arguments optionnels, c'est donc une approche tout ou rien. Vous êtes obligé de laisser à votre méthode le soin de l'appliquer et, évidemment, si votre méthode traite 500 variables, il faudra certainement la refactoriser.
Gary Rowe
@Gary Rowe, que voulez-vous dire par "la plupart des langues ne permettent pas de spécifier une limite sur le nombre d'arguments optionnels"? Dans la plupart des langues, vous les marquez comme telles ou ne leur fournissez pas de valeurs lors de l'appel de la fonction, mais l'en-tête de la fonction a toujours les paramètres définis. Certes, dans certaines langues, vous pouvez ajouter autant de paramètres que vous le souhaitez après avoir rempli les paramètres définis, mais je ne pense pas que ce soit le type de paramètres facultatifs dont nous parlons ici. (à l'exception de l'exception de format de chaîne)
CaffGeek
2

L'un des problèmes avec les paramètres par défaut en C # (je pense que DoSomething vide (int x = 1)) est qu'ils sont constants. Cela signifie que si vous modifiez la valeur par défaut, vous devrez recompiler tous les consommateurs de cet appel de méthode. Bien que cela soit assez facile à faire, il y a des occasions où cela est dangereux.

Po-ta-toe
la source
1

Cela dépend de ce que fait votre code. S'il existe des valeurs par défaut raisonnables, vous devez utiliser des paramètres facultatifs, mais s'il n'y a pas de valeurs par défaut sensibles, l'ajout de paramètres facultatifs rendra votre code plus compliqué. Dans de nombreux cas, les paramètres facultatifs sont un bon moyen de contourner les vérifications nulles et de couper la logique de branchement. Javascript n'a pas de paramètres optionnels mais il existe un moyen de les émuler avec || (logique ou) et je l'utilise tout le temps lorsque je fais des choses liées à la base de données parce que si l'utilisateur ne fournit pas de valeur, je remplace mes propres valeurs à l'aide de || ce qui me sauve la peine d'écrire tout un tas de déclarations if then.

davidk01
la source
1

Les paramètres facultatifs sont un excellent moyen de rendre des choses simples simples et compliquées possibles simultanément. S'il y a un défaut clair et raisonnable que la plupart des utilisateurs voudront, au moins dans les cas d'utilisation rapides et sales, alors ils ne devraient pas avoir à écrire un passe-partout pour le spécifier manuellement chaque fois qu'ils appellent votre fonction. D'un autre côté, si les gens peuvent avoir une bonne raison de vouloir le changer, il doit être exposé.

L'utilisation d'une classe est à mon humble avis une solution terrible, car elle est verbeuse, inefficace et incompatible avec le modèle mental typique de ce qu'une classe fait. Une fonction est l'abstraction parfaite d'un verbe, c'est-à-dire faire quelque chose et retourner. Une classe est l'abstraction correcte pour un nom, c'est-à-dire quelque chose qui a un état et qui peut être manipulé de plusieurs manières. Si le premier doit être le modèle mental de l'utilisateur de l'API, alors n'en faites pas une classe.

dsimcha
la source
1

Le problème avec les arguments facultatifs est que les gens ont tendance à simplement ajouter de plus en plus (et plus) d'arguments à la fonction au lieu d'extraire le code pertinent dans une nouvelle fonction. Ceci est poussé à l'extrême en php . Par exemple:

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
                      [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
Martin Wickman
la source
1

Les paramètres facultatifs sont fondamentalement une manière différente de surcharger une fonction. Donc, cela revient essentiellement à: "la surcharge d'une fonction est-elle mauvaise"?

Pieter B
la source
1

J'ai d'abord adoré cette fonctionnalité en python, et je l'ai utilisée pour «étendre» les méthodes déjà utilisées. Et ça avait l'air sympa et facile, mais ça a vite reculé; parce que lorsque j'ai ajouté un paramètre facultatif, cela modifiait le comportement d'une méthode existante sur laquelle l'ancien client s'appuyait et d'une manière qui n'était pas détectée par les cas de tests unitaires existants. Fondamentalement, cela enfreint le principe ouvert et fermé; le code est ouvert pour l'extension mais fermé pour modification. Je pense donc que l'utilisation de cette fonctionnalité pour modifier le code existant n'est pas une bonne idée; mais d'accord si utilisé dès le départ

Alex Punnen
la source
0

Je pense qu'il serait préférable de surcharger une fonction avec des signatures différentes (c'est-à-dire des paramètres) que d'utiliser des paramètres facultatifs.

HardCode
la source
Pourquoi? Je pense que c'est plus propre si vous pouvez combiner un tas de méthodes surchargées en une seule méthode en utilisant des paramètres par défaut si toutes les méthodes ont les mêmes fonctionnalités de base
Amit Wadhwa
Vous pouvez penser ça. Je ne suis pas du genre à penser que Microsoft fait tout de la bonne façon, mais si vous étiez précis, je ne verrais jamais de surcharges lors de l'utilisation du framework .NET, juste une énorme signature de fonction - comme dans l'ol 'VB6.
HardCode