La chose la plus importante à retenir est que ce sont des lignes directrices, pas des règles.
Il y a des cas où une méthode doit simplement prendre un argument. Pensez à la +
méthode des nombres, par exemple. Ou la add
méthode pour une collection.
En fait, on pourrait même dire que ce que cela signifie d'ajouter deux nombres dépend du contexte, par exemple dans ℤ 3 + 3 == 6
, mais dans ℤ | 5 3 + 3 == 2
, donc vraiment l'opérateur d'addition devrait être une méthode sur un objet de contexte qui prend deux arguments au lieu d'un méthode sur les nombres qui prend un argument.
De même, une méthode pour comparer deux objets doit être soit une méthode d'un objet prenant l'autre comme argument, soit une méthode du contexte, prenant deux objets en argument, donc il n'a tout simplement pas de sens d'avoir une méthode de comparaison avec moins d'un argument.
Cela dit, deux choses peuvent être faites pour réduire le nombre d'arguments pour une méthode:
- Rendre la méthode elle-même plus petite : peut-être que si la méthode a besoin d'autant d'arguments, elle en fait trop?
- Une abstraction manquante : si les arguments sont étroitement corrélés, peut-être qu'ils vont ensemble et qu'il y a une abstraction qui vous manque? (Exemple de manuel canonique: au lieu de deux coordonnées, passez un
Point
objet, ou au lieu de transmettre un nom d'utilisateur et un e-mail, passez un IdCard
objet.)
- État de l'objet : si l'argument est requis par plusieurs méthodes, il doit peut-être faire partie de l'état de l'objet. S'il n'est nécessaire que par certaines des méthodes mais pas par d'autres, peut-être que l'objet en fait trop et devrait en fait être deux objets.
Une façon est d'extraire les arguments dans une nouvelle classe, mais cela conduirait sûrement à une explosion de classes?
Si votre modèle de domaine comporte de nombreux types de choses, votre code se retrouvera avec de nombreux types d'objets différents. Il n'y a rien de mal à cela.
Et ces classes sont susceptibles de se retrouver avec des noms qui violent certaines des règles de dénomination (se terminant par "Data" ou "Info", etc.)?
Si vous ne trouvez pas un nom correct, vous avez peut-être regroupé trop d'arguments ou trop peu. Donc, soit vous avez juste un fragment d'une classe, soit vous avez plus d'une classe.
Une autre technique consiste à faire des variables utilisées par plusieurs fonctions une variable membre privée pour éviter de les transmettre, mais cela étend la portée de la variable, éventuellement de telle sorte qu'elle soit ouverte aux fonctions qui n'en ont pas réellement besoin.
Si vous avez un groupe de méthodes qui fonctionnent toutes sur les mêmes arguments, et un autre groupe de méthodes qui ne le font pas, elles appartiennent peut-être à différentes classes.
Notez combien de fois j'ai utilisé le mot «peut-être»? C'est pourquoi ce sont des lignes directrices, pas des règles. Peut-être que votre méthode avec 4 paramètres est parfaitement bien!