Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Surcharger l’incrémentation dans une classe

[new:30/07/2014]Après avoir parlé des dangers de l’incrémentation dans un contexte multitâche parlons de cet opérateur positivement en montrant comment le surcharger dans une classe et l’intérêt qu’on peut y trouver…

Une possibilité trop peu utilisée : la surcharge des opérateurs

Surcharger ou non les opérateurs est une question clivante

Il y a ceux qui sont totalement pour, et ceux qui sont contre. Rarement il n’existe de position intermédiaire.

Les arguments contre la surcharge sont connus : un opérateur qui n’a pas la même signification partout est un piège à bogues et les attire comme un aimant attire la limaille de fer… Ce n’est pas faux.

Les arguments pour la surcharge sont tout aussi simples : c’est une possibilité du langage aucune raison de ne pas s’en servir… Ce n’est pas faux non plus.

La position de Dot.Blog ? Si certains pensent que la vérité est ailleurs, elle est pour moi bien plus souvent au milieu. Je dirais que personnellement je déconseille d’utiliser la surcharge sauf quand celle-ci apporte de la lisibilité et de la clarté au code et que même si on ne sait pas que cette surcharge a été faite l’effet obtenu sera logique et compréhensible…

Il ne s’agit donc pas de “trop” ou de “trop peu”, mais uniquement de logique, de bon sens et de mesure.

Exemple : Incrémenter les faces d’un polyèdre

Regardons rapidement le GIF animé ci-dessous :

incoverride

Nous disposons d’une classe Polyhedron (polyèdre en anglais). Un Polyèdre est défini comme un volume constitué de plusieurs faces. Les Faces, et leur nombre précis, sont ainsi l’information essentielle et centrale des instances de la classe peu importe ensuite ce qu’elle fait (dessiner le polyèdre par exemple).

Dans une telle classe il peut être intéressant non pas de surcharger mais simplement de définir un opérateur d’incrémentation (et de décrémentation, ce qui n’est pas fait dans l’exemple). Ainsi au lieu d’écrire MonPolyèdre.Faces = MonPolyèdre.Faces+1 on écrira de façon plus concise MonPolyèdre++;

Le sens de l’incrémentation est parfaitement respecté, cela reste logique et compréhensible. Si on ne sait pas que l’opérateur est défini on comprendra assez facilement qu’un “++” sur un polyèdre augmente le nombre de faces.

On peut d’ailleurs utiliser cette technique pour rendre l’incrémentation thread-safe en utilisant Interlocked.Increment() dans la définition ou redéfinition de l’opérateur. Dans ce cas on introduit une différence fonctionnelle importante et celle-ci doit être dument documentée…

Conclusion

Comme toutes les bonnes choses il ne faut pas abuser de cette technique car elle introduit tout de même un sens qui n’est pas celui de l’opérateur à l’origine. Incrémenter un nombre de faces par Faces++ est parfaitement logique et ne réclame aucune information en dehors de la connaissance du langage, mais MonPolyèdre++ est déjà plus étrange même s’il y a une logique claire sous-jacente. Incrémenter un polyèdre n’a stricto sensu pas de signification.

Si on fait bien attention à cette distorsion de sens, qu’elle est documentée, et que l’apport est réellement intéressant dans le contexte alors se priver de cette possibilité de redéfinir les opérateurs n’est pas acceptable, le langage le permet, autant s’en servir.

On retrouve ici la position médiane exprimée plus haut. Ni pour, ni contre, au milieu je suis… comme aurait pu dire Me Yoda…

Surchargez bien, mais attention à ne pas écraser le code sous ce poids !

Et ? …. Bien entendu on … Stay Tuned !

blog comments powered by Disqus