71 votes

Une classe utilitaire doit-elle être statique ?

Si je dois concevoir une classe utilitaire (telle que ByteUtils ou StreamUtils ou StringUtils), quel est le meilleur choix de conception pour elles.

  • Doivent-elles être des classes statiques (car je n'aurai pas d'états à stocker) ?
  • Doit-il s'agir de classes non statiques (de sorte que si les objets ne sont pas utilisés, ils seront récupérés) ?

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

Pouvez-vous nous conseiller sur les choix de conception à faire ?

64voto

JB Nizet Points 250258

Mes classes d'utilité 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 qui les utilisent difficiles à tester en unité, parce qu'il n'est pas facile de simuler ces méthodes utilitaires. Le fait d'avoir trop de classes utilitaires de ce type peut être le signe d'un manque de conception OO (programmation procédurale), et peut vraiment rendre le code difficile à tester.

Si vous utilisez un framework d'injection de dépendances (Spring, Guice, etc.), il peut être judicieux de rendre la classe utilitaire instanciable, avec des méthodes non statiques, et d'en faire un singleton injectable. De cette façon, les classes qui utilisent ces méthodes utilitaires peuvent être testées en simulant l'objet utilitaire.

45voto

Gapton Points 929

S'il s'agit d'un utilitaire à usage général, le statique est préférable. Vous avez déclaré que vous n'aurez pas d'états à stocker, donc je ne vois pas pourquoi vous devriez le rendre non statique. En le déclarant statique, vous économiserez également de la mémoire.

24voto

mrbaboo Points 300

Ce n'est pas parce qu'une chose peut être statique qu'elle doit l'être.

Il y a une autre considération à tout cela : le mocking. Il est plus difficile de simuler 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'objets me semble être une optimisation prématurée. La JVM fait un très bon travail d'optimisation pour éviter ce genre de problème.

9voto

Peter Lawrey Points 229686

La manière la plus simple de définir une classe d'utilité est de la considérer comme une énumération sans instances.

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

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

Vous pouvez avoir d'autres classes à état pour des buts spécifiques comme Builder, Factory, vous pouvez créer l'objet comme vous le souhaitez et le jeter quand vous avez fini.

4voto

Venkat Points 1

Il est bon de rendre la classe non statique avec un constructeur privé :

  • si nous rendons la classe statique, elle sera chargée lorsque l'application sera déployée ; si elle est non statique, elle sera chargée lorsqu'un appel sera fait à l'une de ses méthodes statiques.
  • la création d'un constructeur privé évitera l'instanciation de la classe

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X