Pourquoi rendre certaines méthodes pour les types de données statiques ?
En C #, par exemple, il existe des méthodes statiques pour dire si une chaîne est null ou vide , trouver un élément dans un tableau, effacer un tableau, etc. Cependant, il existe une méthode d'instance pour remplacer les caractères dans une chaîne, et à la fois statique et instance méthodes de copie d'éléments entre tableaux.
De même, en Python, il existe des fonctions pour obtenir la longueur d'une liste, pour filtrer une liste, etc., mais des méthodes d'instance pour trouver l'index d'un élément et pour copier la liste.
Au contraire, en JavaScript, pratiquement toutes les opérations que je dois effectuer sur un type de données intégré seront accessibles via une méthode ou une propriété d'instance.
Alors, quelle est la raison de rendre certaines choses statiques et d'autres non ?
EDIT : Pour être clair, je comprends le but des méthodes statiques. Ma question porte davantage sur la raison pour laquelle certaines méthodes sont écrites comme statiques alors qu'elles auraient pu être écrites comme des méthodes d'instance. Comme Find
pour les tableaux et Format
pour les chaînes en C#, et filter
et len
en Python.
Réponses
EDIT : la question a été affinée, je vais donc affiner ma réponse, mais laissez la précédente ci-dessous afin de ne pas rendre les commentaires non pertinents.
Il peut y avoir plusieurs raisons d'implémenter une méthode en tant que méthode statique au lieu d'une méthode d'instance, avec différents langages ou frameworks ayant éventuellement des justifications différentes :
L'interface publique d'un objet est un contrat. Si votre
Array
type expose uneSort
méthode, chaque tableau à partir de maintenant, quel que soit le type ou la version du langage, doit la prendre en charge. Si, toutefois, anArray
n'est qu'une représentation de données en mémoire avec un contrat léger et que la logique est déplacée vers une classe telle queArray.Sort
, cela vous donne plus de flexibilité pour étendre ou modifier votre comportement sans rompre la compatibilité.Voir cette citation du Clean Code de Bob Martin :
Les objets exposent le comportement et cachent les données ; La structure des données expose les données et n'a pas de comportement significatif"
Dans ce cas, la List
classe est une classe qui expose le comportement - elle cache ses données (elle est implémentée comme un tableau redimensionnable, mais c'est un détail d'implémentation), mais expose les fonctionnalités. Un int[]
, cependant, est une structure de données. int
C'est un bloc alloué séquentiellement . Il a une Length
propriété car il fait partie de ses données , mais n'a pas beaucoup de comportement - le comportement est transféré à une classe qui opère dessus.
- C'est peut-être un choix stylistique. Python n'est pas un langage purement OO et peut ne pas avoir la garantie Java/C # "tout est un objet", il a donc choisi d'utiliser des fonctions de langage comme
len()
celles-ci pouvant être utilisées, que son paramètre soit une instance d'objet ou non.
Réponse précédente
La raison d'être des méthodes statiques en C# est d'avoir des méthodes qui sont liées à un type mais pas à une instance . Il peut y avoir plusieurs raisons à cela :
- Les méthodes qui peuvent fonctionner à la fois sur une instance et
null
, commestring.IsNullOrEmpty
, ne peuvent naturellement pas être des méthodes d'instance - car il se peut qu'il n'y ait pas d'instance. - De même, les méthodes de fabrique qui créent une instance n'ont pas d'instance à partir de laquelle elles peuvent être appelées. Par exemple, la méthode statique obsolète de quelqu'un
WebRequest.Create()
renvoie une nouvelle instance d'un type dérivé deWebRequest
. - Bien qu'il soit facile d'oublier, .NET a une gestion différente pour un type intégral natif (
int i =5
) et un type de référence encadré autour de lui (object boxed = 5
). Si vous appelez une méthode sur un type valeur (int i = 5; t.ToString();
), vous encourez un coût de mise en boîte. C'est pourquoi certaines opérations ne sont pas définies comme une méthode sur un objet, mais comme une méthode statique qui accepte une valeur. C'est pourquoi les opérations mathématiques telles queMath.Abs
ne sont pas définies comme des méthodes sur les types encadrés, mais comme des fonctions statiques qui reçoivent et renvoient des valeurs. - Parfois, des méthodes statiques sont utilisées pour "configurer" un type, pas une instance spécifique mais le comportement de ce type dans le système. Par exemple,
[ServicePointManager.SetTcpKeepAlive()][1]
configure le comportement de toutes les classes qui utilisent la pile HTTP(s) partagée dans .NET, afin que vous puissiez toutes les configurer via ces méthodes statiques.
Les méthodes statiques ont beaucoup de sens
- lorsque la méthode est liée au type mais ne nécessite pas d'instance existante ; ou
- lorsque le langage prend en charge l'espace de noms uniquement via des classes.
C# ne prend en charge que les fonctions en tant que membres de classes, de sorte que les fonctions d'assistance doivent être écrites en tant que méthodes statiques. La classe C# Math
en est un excellent exemple.
JavaScript n'a pas de classes, mais chaque variable non locale est associée à un objet - dans le navigateur, la plupart des API sont accessibles via l' window
objet. Cependant, certaines méthodes sont accessibles via un objet de type classe, par exemple Array.isArray(x)
.
Python a une conception idiosyncrasique qui est principalement orientée objet, mais possède certaines fonctions intégrées comme len()
ou iter()
, en grande partie pour des raisons historiques. Sous le capot, ils invoquent des méthodes réelles, par exemple iter(x)
est généralement x.__iter__()
, avec une solution de repli pour les objets qui peuvent être indexés comme une liste.
Plus intéressantes sont les méthodes qui ne sont static
pas dues aux bizarreries du langage, mais parce que cela a du sens. Les méthodes de type constructeur ou de type usine sont l'exemple classique où nous n'avons pas d'objet existant sur lequel nous pourrions appeler une méthode. Certaines fonctions n'opèrent pas non plus sur exactement un objet, par exemple String.IsNullOrEmpty(x)
opèrent sur zéro ou un objet. Cela ne fonctionne pas comme une méthode, par exemple x.IsNullOrEmpty()
lèverait une exception si elle est nulle ! La Array.isArray(x)
méthode en JS est un autre excellent exemple : nous voulons appeler isArray(x)
des objets de n'importe quel type, pas seulement des tableaux. Ainsi, une méthode d'instance ne fonctionne que si elle fait partie du prototype de chaque objet.