Pourquoi créer un objet Logger au lieu d'utiliser des méthodes de journalisation statique dans une application?

14

Prenons un exemple d'une simple application Ruby on Rails. Il crée un Loggerobjet pendant le processus de chargement d'application:

# in environment.rb
config.logger = Logger.new(<STDOUT | file | whatever>)

# and in our application we use this object
logger.warn "This process is taking too long to process. Optimization needed."

Ma question est, pourquoi n'utilisons-nous pas des méthodes de classe (ou des méthodes statiques) pour la journalisation? Ne sera pas mis à l' Logger.warnéchelle que Logger.new.warn? Ou du moins Logger.warnsemble intuitif Logger.new.warn.

Même s'il Logger.news'agit d'un objet singleton, quels avantages offre-t-il?

Harsh Gupta
la source

Réponses:

17

Voici un exemple qui utilise Java. Cela fait un moment que je n'ai pas utilisé log4j, mais d'après ce que je me souviens, l'ensemble de l'outil de journalisation log4j s'initialiserait à partir d'un fichier XML. Le fichier XML lui-même peut contenir plusieurs enregistreurs avec différentes configurations (où vous écrivez, à quels niveaux sont écrits, etc.). Donc, dans ce cas, vous auriez des objets de journalisation plutôt que des méthodes statiques de journalisation afin de spécifier le logger que vous souhaitez invoquer. C'est à dire.

Logger logger = Logger.get("Network");

enregistrerait des éléments liés à la connectivité réseau, aux paquets perdus, etc., ou

Logger logger = Logger.get("Application");

qui consignerait les éléments liés à votre logique / application métier. Au moins avec log4j, vous pouvez également configurer les niveaux de journal réellement écrits (info, trace, warn, error, debug étant les niveaux par défaut disponibles).

Si vous aviez des méthodes statiques, le mieux que vous puissiez faire est de configurer un seul enregistreur qui pointerait vers la sortie standard, un fichier, etc., mais tout ce que vous enregistrez irait au même endroit. Avec les objets de journalisation, il est plus facile de le faire afin que vos informations de journalisation soient réparties sur plusieurs fichiers.

Shaz
la source
Merci. Cela a également aidé à comprendre quand utiliser des méthodes statiques.
Harsh Gupta
2
Bien que je préfère instancier un objet pour faire ma journalisation, comme démontré ici, il est assez courant (je dirais préférable) d'y accéder statiquement plutôt que de le passer dans chaque appel de méthode. La journalisation est de nature globale.
Chad Schouggins
Il convient également de noter qu'il y a des moments où nous pourrions vouloir configurer l'enregistreur en l'étendant (ou en fournissant une implémentation d'une interface et en fournissant cela à l'enregistreur). Cela serait utilisé pour faire quelque chose comme changer la destination de journalisation (au-delà de ce que les fichiers de configuration pourraient permettre). Vous rendriez probablement l'instance spécifique statique, cependant, comme l'a mentionné @ChadSchouggins.
Kat
2

Logger.new est une fabrique qui prendra où le résultat sera utilisé (nom de la classe / du fichier).

Dans les fichiers de configuration, vous pouvez alors décider du niveau à enregistrer pour ne pas enregistrer du tout pour certaines parties du programme sans avoir à recompiler le projet.

Ainsi, vous pouvez désactiver tout sauf la journalisation de haut niveau (erreurs) pour les versions de version et activer uniquement le niveau le plus bas pour les parties que vous déboguez.

monstre à cliquet
la source
2

L'invocation de méthode statique doit être évitée autant que possible. C'est une alternative désuète à l'injection de dépendance appropriée, et ce n'est pas quelque chose que vous trouverez utile dans une base de code plus grande.

Prenons l'exemple de la testabilité. L'invocation statique de la journalisation place le sujet sous test dans le contrôle de la classe de journalisation utilisée - il n'y a pas d'inversion de contrôle. Il n'y a aucune possibilité d'injecter un faux objet ou tout autre type de faux ici. En injectant l'enregistreur dans le SUT, vous constaterez que vous avez la possibilité de vous moquer de l'enregistreur et de l'injecter.

Bien entendu, les avantages de l'utilisation de DI sur le type d'invocation de méthode statique en cours de discussion vont au-delà de la testabilité. Considérez ce qui se passerait si vous souhaitiez avoir deux enregistreurs différents dans votre système et l'option de changer le comportement de l'application par la configuration du graphique d'objet seul, sans modifier le code existant.

Dans l'ensemble, je vous suggère d'essayer une approche DI, afin que vous ne trouviez pas votre code non testable et peu maniable plus tard.

Sam Burns
la source