Une classe d’utilité devrait-elle être statique?

Si je dois concevoir une classe Utility (telle que ByteUtils ou StreamUtils ou SsortingngUtils), quel est le meilleur choix de conception pour eux.

  • Devraient-ils être des classes statiques (comme je n’aurai pas d’états à stocker)
  • Devraient-ils être des classes non statiques (de sorte que si les objects ne sont pas utilisés, ils seront gc’d)

PS: Par classe statique, je voulais dire une classe avec des méthodes statiques (et non la classe statique interne)

S’il vous plaît donner des conseils sur les choix de conception pour cela?

Si c’est un utilitaire à usage général, le statique est mieux IMO. Vous avez déclaré que vous n’auriez pas d’états à stocker, alors je ne vois pas pourquoi vous devriez le rendre non statique. Le déclarer statique permettra également d’économiser de la mémoire.

Mes classes d’utilitaires ressemblent à ceci:

// final, because it's not supposed to be subclassed public final class FooUtil { // private constructor to avoid unnecessary instantiation of the class private FooUtil() { } public static int doSomethingUseful() { } // ... } 

Notez que, bien que cela rende les méthodes utilitaires facilement testables et facilement accessibles de l’extérieur, cela rend également les classes difficiles à tester, car il n’est pas facile de se moquer de ces méthodes utilitaires. Avoir trop de telles classes d’utilitaires peut être le signe d’un manque de conception OO (programmation procédurale), et peut réellement rendre le code difficile à tester.

Si vous utilisez un framework d’dependency injections (Spring, Guice, etc.), il serait peut-être judicieux de rendre la classe d’utilitaire instantanée, avec des méthodes non statiques, et d’en faire un singleton injectable. De cette façon, les classes utilisant ces méthodes utilitaires peuvent être testées en moquant l’object utilitaire.

Ce n’est pas parce que quelque chose peut être statique que cela devrait être statique.

Il y a une autre considération à tout cela: se moquer. Il est plus difficile de se moquer des méthodes statiques dans vos tests que de simuler le comportement d’une instance d’une classe.

Parler d’allocations de tas inutiles et de GCing d’objects présente une optimisation prématurée pour moi. La JVM fera un très bon travail pour optimiser ce type de problème.

Le moyen le plus simple de définir une classe Utility est une énumération sans instance

 public enum Utility {; public static int utilityMethod(int x) { /* ... */ } } 

Une classe d’utilitaires ne devrait avoir aucun état ou avoir un état minimal, vous ne devriez donc pas vous soucier des GC.

Vous pouvez avoir d’autres classes avec état à des fins spécifiques comme Builder, Factory, vous pouvez créer l’object comme vous le souhaitez et le supprimer lorsque vous avez terminé.

C’est bien de rendre la classe non statique avec un constructeur privé:

  • si on fait la classe static alors la classe sera chargée quand l’application est déployée, si elle est non statique alors la classe sera chargée quand il y aura un appel à une de ses méthodes statiques
  • créer un constructeur privé évitera d’instancier la classe

Habituellement, les classes utilitaires contiennent des méthodes statiques et aucun atsortingbut, cette approche facilite l’utilisation de leurs méthodes sans instancier la classe. J’espère que cela t’aides.

Si vous pouvez les rendre statiques, alors certainement le faire!

En d’autres termes, s’ils n’ont pas d’état, ils devraient être statiques.

Eh bien, si vous n’avez pas d’état à stocker, il n’y a rien à GC, donc j’irais avec statique, de cette façon, vous éviterez les allocations de tas inutiles et GC.

Les classes d’utilitaires pures devraient généralement être statiques. Lorsque vous avez une classe avec des entrées et des sorties bien définies, sans effets secondaires et sans état, alors, par définition, cela devrait être une classe statique.

En règle générale, n’ajoutez pas de complexité (dependency injection dans ce cas) avant que cela soit nécessaire et qu’il y ait un avantage à le faire.

Personne ici ne mentionne que les méthodes d’utilitaires statiques ne sont pas extensibles. Vous ne pouvez pas les remplacer. Vous ne pouvez pas tirer parti de la POO (en particulier du polymorphism, qui est la caractéristique la plus puissante de la POO). Cela conduit à la duplication de code.

PS J’ai trouvé cet article très utile. http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html