Adresser une API existante: Utiliser argument par défaut ou la fonction d'emballage?

StackOverflow https://stackoverflow.com/questions/940877

  •  06-09-2019
  •  | 
  •  

Question

J'ai une méthode existante (ou une fonction en général) que je dois développer des fonctionnalités supplémentaires, mais je ne veux pas briser l'utilisation de la méthode ailleurs dans le code. Exemple:

int foo::bar(int x)
{
 // a whole lot of code here
 return 2 * x + 4;
}

est largement utilisé dans la base de code. Maintenant, je dois faire 4 en un paramètre, mais tout code qui appelle déjà la barre de foo devrait toujours recevoir ce qu'il attend. Dois-je étendre et renommer l'ancienne méthode et l'envelopper dans un nouveau comme

int foo::extended_bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

int foo::bar(int x)
{
 return extended_bar(x,4);
}

ou dois-je déclarer un argument par défaut dans le fichier d'en-tête comme

int bar(int x, int y=4);

et étendre simplement la fonction

int foo::bar(int x, int y)
{
 // ...
 return 2 * x + y;
}

Quels sont les avantages et les inconvénients de chaque variante?

Était-ce utile?

La solution

J'utilise généralement un fonction enveloppe (via la surcharge la plupart du temps) au lieu des paramètres par défaut.

La raison est qu'il ya deux niveaux de rétrocompatibilité :

  1. Avoir source de niveau rétrocompatibilité signifie que vous devez recompiler le code d'appel sans changement, parce que les nouvelles signatures de fonction sont compatibles avec les anciens. Ce niveau peut être atteint avec les deux; les valeurs par défaut et wrappers / surcharge.

  2. Un niveau plus fort est niveau binaire compatibilité descendante, qui fonctionne même sans recompilation, par exemple lorsque vous n'avez pas accès au code d'appel. Imaginez que vous déployez votre fonction sous forme binaire, comme dans une DLL, etc. Dans ce cas, les signatures ont l'être exactement la même chose pour le faire fonctionner, ce qui est le cas pour les valeurs par défaut - ils briser ce niveau de compatibilité .

Un autre avantage des fonctions wrapper est - si votre application a l'enregistrement de toute nature - vous pouvez jeter un avertissement dans l'ancienne fonction qu'elle deviendra obsolète dans les versions futures et qu'il est recommandé d'utiliser le nouveau

Autres conseils

Plus j'utilise C ++, moins j'aime les paramètres de fonction par défaut. Je ne peux pas mettre le doigt sur une raison particulière pour mon aversion, mais je trouve que si je les utilise, je finis presque toujours les retirer plus tard. Donc, mon (subjective) vote va pour la nouvelle fonction nommée -. Le nom pourrait bien sûr être identique à celui de l'ancien

Je crois personnellement que les comportements implicites sont (un) les racines du mal.

Tout ce qui obscurcit un mainteneur ou appelant l'identité de la cible étant invoquée devrait avoir une justification très forte, surtout si elle fait partie d'une API majeure.

Par conséquent, je soutiens fermement contre l'option avec l'opération par défaut.

En outre, je crois que si une certaine fonction peut être invoquée avec un nombre différent de paramètres, alors il y a quelque chose d'intrinsèquement différent des deux versions de la fonction ou ils font trop. La distinction devrait probablement être au nom, et devrait probablement être plus significatif que « _extended »

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top