Ne jamais dire jamais"
Je ne pense pas que ce soit nécessairement mauvais, c'est seulement mauvais si vous le faites mal et en abusez.
Nous avons tous besoin d'outils et d'utilitaires
Pour commencer, nous utilisons tous des bibliothèques qui sont parfois considérées comme presque omniprésentes et incontournables. Par exemple, dans le monde Java, Google Guava ou certains d' Apache Commons ( Apache Commons Lang , Apache Commons Collections , etc ...).
Il y a donc clairement un besoin pour cela.
Évitez les mots durs, la duplication et l'introduction de bogues
Si vous pensez à ce sont à peu près juste un groupe très grand de ces Util
classes que vous décrivez, sauf que quelqu'un est passé par beaucoup de mal pour les obtenir (relativement) à droite, et ils ont été le temps - testé et fortement balled les yeux par d' autres.
Donc, je dirais que la première règle générale lorsque vous ressentez la démangeaison d'écrire une Util
classe est de vérifier que la Util
classe n'existe pas déjà.
Le seul contre-argument que j'ai vu pour cela est quand vous voulez limiter vos dépendances parce que:
- vous souhaitez limiter l'empreinte mémoire de vos dépendances,
- ou vous voulez contrôler étroitement ce que les développeurs sont autorisés à utiliser (cela se produit dans de grandes équipes obsessionnelles, ou lorsqu'un framework particulier est connu pour avoir la classe super-merdique étrange à éviter absolument quelque part).
Mais ces deux éléments peuvent être résolus en reconditionnant la bibliothèque à l' aide de ProGuard ou un équivalent, ou en le démontant vous-même (pour les utilisateurs de Maven , le plug-in maven - shadow offre certains modèles de filtrage pour l'intégrer dans votre build).
Donc, s'il se trouve dans une bibliothèque et correspond à votre cas d'utilisation, et qu'aucun benchmark ne vous dit le contraire, utilisez-le. Si cela diffère un peu de ce que vous, étendez-le (si possible) ou étendez-le, ou en dernier recours réécrivez-le.
Conventions de nommage
Cependant, jusqu'à présent dans cette réponse, je les ai appelés Util
comme vous. Ne les nommez pas ainsi.
Donnez-leur des noms significatifs. Prenez Google Guava comme (très, très) bon exemple de ce qu'il faut faire, et imaginez simplement que l' com.google.guava
espace de noms est en fait votre util
racine.
Appelez votre forfait util
, au pire, mais pas les cours. S'il s'agit d' String
objets et de manipulation de constructions de chaînes, appelez Strings
-le non StringUtils
(désolé, Apache Commons Lang - je vous aime et vous utilise toujours!). S'il fait quelque chose de spécifique, choisissez un nom de classe spécifique (comme Splitter
ou Joiner
).
Test de l'unité
Si vous devez recourir à l'écriture de ces utilitaires, assurez-vous de les tester à l'unité. La bonne chose à propos des utilitaires est qu'ils sont généralement des composants plutôt autonomes, qui acceptent des entrées spécifiques et renvoient des sorties spécifiques. Voilà le concept. Il n'y a donc aucune excuse pour ne pas les tester à l'unité.
De plus, les tests unitaires vous permettront de définir et de documenter le contrat de leur API. Si les tests échouent, soit vous avez changé quelque chose dans le mauvais sens, soit cela signifie que vous essayez de changer le contrat de votre API (ou que vos tests originaux étaient de la merde - apprenez-en et ne recommencez pas) .
Conception d'API
La décision de conception que vous prendrez pour ces API vous suivra peut-être longtemps. Donc, tout en ne passant pas des heures à écrire un Splitter
-clone, faites attention à la façon dont vous abordez le problème.
Posez-vous quelques questions:
- Votre méthode d'utilité justifie-t-elle une classe à elle seule, ou une méthode statique est-elle suffisamment bonne, si elle a un sens pour qu'elle fasse partie d'un groupe de méthodes similaires utiles?
- Avez-vous besoin de méthodes d'usine pour créer des objets et rendre vos API plus lisibles?
- En parlant de lisibilité, avez-vous besoin d'une API Fluent , de constructeurs , etc ...?
Vous voulez que ces utilitaires couvrent un large éventail de cas d'utilisation, qu'ils soient robustes, stables, bien documentés, selon le principe de la moindre surprise, et qu'ils soient autonomes. Idéalement, chaque sous-ensemble de vos utilitaires, ou votre ensemble complet d'utilisation au moins, doit être exportable en un ensemble pour une réutilisation facile.
Comme d'habitude, apprenez des géants ici:
Oui, beaucoup d'entre eux mettent l'accent sur les collections et les structures de données, mais ne me dites pas que ce n'est pas où ni pour quoi vous êtes généralement susceptible d'implémenter la plupart de vos utilitaires, directement ou indirectement.
Util
dans les noms de vos classes. Problème résolu.