web-dev-qa-db-fra.com

Est-ce une mauvaise pratique pour une classe de n'avoir que des champs et des méthodes statiques?

J'ai une classe qui se compose uniquement de variables membres statiques et de méthodes statiques. Essentiellement, il sert de classe utilitaire à usage général.

Est-ce une mauvaise pratique qu'une classe contienne uniquement des variables membres statiques et des méthodes statiques?

70
Stephen Watkins

Non, je ne pense pas du tout. Il est pire d'avoir une classe pleine de méthodes d'instance qui ne dépendent pas réellement d'une instance particulière. Les rendre statiques indique à l'utilisateur exactement comment elles doivent être utilisées. De plus, vous évitez ainsi les instanciations inutiles.

EDIT: Après coup, en général, je pense qu'il est agréable d'éviter d'utiliser les fonctionnalités du langage "juste parce que", ou parce que vous pensez que c'est la "façon Java de le faire". Je me souviens de mon premier travail où j'avais une classe pleine de méthodes utilitaires statiques et l'un des programmeurs seniors m'a dit que je ne maîtrisais pas complètement la puissance OO de Java en rendant toutes mes méthodes "globales". Elle n'était pas dans l'équipe 6 mois plus tard.

88
danben

Tant que la classe n'a pas d'état interne et est essentiellement ce qu'on appelle une classe feuille (les classes d'utilité entrent dans cette catégorie), en d'autres termes, elle est indépendante des autres classes. C'est bon.

La classe Math est un excellent exemple.

18
Finglas

Semble raisonnable.

Remarque: Les classes qui font cela ont souvent un constructeur privé sans argument juste pour que le compilateur génère une erreur si un programmeur essaie de créer une instance de la classe statique.

13
Jason S

Les méthodes statiques ne m'inquiètent pas beaucoup (sauf pour les tests).

En général, les membres statiques sont une préoccupation. Par exemple, que se passe-t-il si votre application est en cluster? Qu'en est-il du temps de démarrage - quel type d'initialisation a lieu? Pour un examen de ces questions et plus, consultez cet article par Gilad Bracha.

9
Michael Easter

C'est parfaitement raisonnable. En fait, en C #, vous pouvez définir une classe avec le mot-clé statique spécifiquement à cet effet.

3
Taylor Leese

Ne vous laissez pas emporter. Notez que la classe Java.lang.Math ne concerne que les fonctions mathématiques. Vous pouvez également avoir une classe StringUtilities qui contient des fonctions courantes de gestion des chaînes qui ne sont pas dans l'API standard, par exemple. Mais si votre classe est nommée Utilitaires, par exemple, c'est un indice que vous voudrez peut-être la diviser.

3
Paul Clapham

Notez également que Java a spécifiquement introduit l'importation statique: ( http://en.wikipedia.org/wiki/Static_import )

L'importation statique est une fonctionnalité introduite dans le langage de programmation Java que les membres (champs et méthodes) ont défini dans une classe comme statique publique à utiliser dans Java sans spécifiant la classe dans laquelle le champ est défini. Cette fonctionnalité a été introduite dans le langage dans la version 5.0.

La fonctionnalité fournit un mécanisme de typesafe pour inclure des constantes dans le code sans avoir à référencer la classe qui a initialement défini le champ. Il permet également de déprécier la pratique de créer une interface constante: une interface qui ne définit que des constantes puis d'écrire une classe implémentant cette interface, ce qui est considéré comme une utilisation inappropriée des interfaces [1].

Le mécanisme peut être utilisé pour référencer des membres individuels d'une classe:

 import static Java.lang.Math.PI;
 import static Java.lang.Math.pow;

ou tous les membres statiques d'une classe:

 import static Java.lang.Math.*;
2
peter.murray.rust

Bien que je sois d'accord avec le sentiment que cela semble être une solution raisonnable (comme d'autres l'ont déjà dit), une chose que vous voudrez peut-être considérer, du point de vue de la conception, pourquoi avez-vous une classe uniquement à des fins "d'utilité". Ces fonctionnalités sont-elles vraiment générales sur l'ensemble du système ou sont-elles vraiment liées à une classe spécifique d'objets au sein de votre architecture?.

Tant que vous y avez réfléchi, je ne vois aucun problème avec votre solution.

2
JasCav

Ce lien http://Java.dzone.com/articles/why-static-bad-and-how-avoid semble aller à l'encontre de la plupart des réponses ici. Même si elle ne contient aucune variable membre (c'est-à-dire aucun état), une classe statique peut toujours être une mauvaise idée car elle ne peut pas être mockée ou étendue (sous-classe), donc elle va à l'encontre de certains des principes d'OO

1
Andy

La classe Collections dans Java SDK n'a que des membres statiques.

Donc, vous y allez, tant que vous avez une justification appropriée - ce n'est pas une mauvaise conception

1
Mihir Mathuria

Les méthodes utilitaires sont souvent placées dans des classes avec uniquement des méthodes statiques (comme StringUtils.). Les constantes globales sont également placées dans leur propre classe afin qu'elles puissent être importées par le reste du code (public final static les attributs.)

Les deux utilisations sont assez courantes et ont des constructeurs par défaut privés pour les empêcher d'être instanciées. La déclaration de la classe finale évite l'erreur d'essayer de remplacer les méthodes statiques.

Si par static member variables vous ne vouliez pas dire des constantes globales, vous voudrez peut-être placer les méthodes accédant à ces variables dans une classe à part. Dans ce cas, pourriez-vous expliquer ce que font ces variables dans votre code?

1
rsp

C'est généralement ainsi que les classes d'utilité sont conçues et il n'y a rien de mal à cela. Des exemples célèbres incluent o.a.c.l.StringUtils , o.a.c.d.DbUtils , o.s.w.b.ServletRequestUtils , etc.

1
Pascal Thivent

Selon une interprétation rigide de la conception orientée objet, une classe d'utilité est quelque chose à éviter.

Le problème est que si vous suivez une interprétation rigide, vous devrez forcer votre classe dans un objet de tri afin d'accomplir beaucoup de choses.

Même les Java créent des classes utilitaires (Java.lang.Math me vient à l'esprit)

Vos options sont:

double distance = Math.sqrt(x*x + y*y);  //using static utility class

contre:

RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
   distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.      

Même si nous devions éviter la méthode verbeuse, nous pourrions toujours nous retrouver avec:

Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);

dans ce cas, .sqrt () est toujours statique, alors quel serait l'intérêt de créer l'objet en premier lieu?

La réponse est, créez des classes utilitaires lorsque votre autre option serait de créer une sorte de classe artificielle "Worker" qui n'a pas ou peu d'utilité pour les variables d'instance.

1
Chris Cudmore

Je ne serais pas préoccupé par une classe utilitaire contenant des méthodes statiques.

Cependant, les membres statiques sont essentiellement des données globales et doivent être évités. Elles peuvent être acceptables si elles sont utilisées pour mettre en cache les résultats des méthodes statiques et autres, mais si elles sont utilisées comme de "vraies" données qui peuvent conduire à toutes sortes de problèmes, tels que des dépendances cachées et des difficultés pour configurer des tests.

0
starblue