Warum sollte ein Logger-Objekt erstellt werden, anstatt in einer Anwendung statische Protokollierungsmethoden zu verwenden?

14

Ein Beispiel für eine einfache Ruby on Rails-Anwendung. Es erstellt ein LoggerObjekt während des Ladevorgangs der Anwendung:

# 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."

Meine Frage ist, warum wir nicht Klassenmethoden (oder statische Methoden) für die Protokollierung verwenden? Wird nicht Logger.warnskalieren als Logger.new.warn? Oder zumindest Logger.warnscheint intuitiv als Logger.new.warn.

Logger.newWelche Vorteile bietet ein einzelnes Objekt, selbst wenn es sich um ein einzelnes Objekt handelt?

Harte Gupta
quelle

Antworten:

17

Hier ist ein Beispiel, das Java verwendet. Es ist schon eine Weile her, dass ich log4j verwendet habe, aber soweit ich mich erinnere, wurde das gesamte log4j-Protokollierungstool aus einer XML-Datei initialisiert. Die XML-Datei selbst kann mehrere Logger mit unterschiedlichen Konfigurationen enthalten (wo Sie schreiben, welche Ebenen geschrieben werden usw.). In diesem Fall würden Sie also eher Logger-Objekte als statische Logger-Methoden verwenden, um anzugeben, welche Logger Sie aufrufen möchten. Dh

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

würde Dinge im Zusammenhang mit Netzwerkkonnektivität, verworfenen Paketen usw. protokollieren oder

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

die Dinge im Zusammenhang mit Ihrer Geschäftslogik / -anwendung protokollieren würden. Zumindest mit log4j können Sie auch konfigurieren, welche Protokollebenen tatsächlich ausgeschrieben werden (info, trace, warn, error, debug sind die verfügbaren Standardebenen).

Wenn Sie statische Methoden verwenden, können Sie am besten einen einzelnen Logger konfigurieren, der auf Standardout, eine Datei usw. hinweist, aber alles, was Sie protokollieren, wird an derselben Stelle abgelegt. Mit Logger-Objekten ist es einfacher, diese zu erstellen, damit Ihre Protokollierungsinformationen auf mehrere Dateien verteilt werden.

Shaz
quelle
Vielen Dank. Dies trug auch zum Verständnis der Verwendung statischer Methoden bei.
Harsh Gupta
2
Ich bevorzuge es, ein Objekt zu instanziieren, um meine Protokollierung durchzuführen, wie hier gezeigt, ist es ziemlich üblich (ich würde sagen, bevorzugt), statisch darauf zuzugreifen, anstatt es an jeden Methodenaufruf weiterzuleiten. Protokollierung ist nur eine Art globaler Natur.
Chad Schouggins
Es ist auch zu beachten, dass es Zeiten gibt, in denen wir den Logger konfigurieren möchten, indem wir ihn erweitern (oder eine Implementierung einer Schnittstelle bereitstellen und dies für den Logger bereitstellen). Dies würde verwendet, um so etwas wie das Protokollierungsziel zu ändern (über das hinaus, was Konfigurationsdateien zulassen könnten). Sie würden die spezifische Instanz jedoch wahrscheinlich statisch machen, wie @ChadSchouggins erwähnt hat.
Kat
2

Logger.new ist eine Factory, in der das Ergebnis verwendet wird (Name der Klasse / Datei).

In den Konfigurationsdateien können Sie dann entscheiden, welche Ebene protokolliert werden soll, um Teile des Programms überhaupt nicht zu protokollieren, ohne das Projekt neu kompilieren zu müssen.

Auf diese Weise können Sie alle Protokollierungen (Fehler) außer der Protokollierung auf hoher Ebene für Release-Builds deaktivieren und nur die niedrigste Ebene für die zu debuggenden Teile aktivieren.

Ratschenfreak
quelle
2

Der statische Methodenaufruf sollte nach Möglichkeit vermieden werden. Es ist eine veraltete Alternative zu Dependency Injection und in einer größeren Codebasis nicht hilfreich.

Betrachten Sie zum Beispiel die Testbarkeit. Durch das statische Aufrufen der Protokollierung wird der Prüfling unter Kontrolle gebracht, welche Protokollierungsklasse verwendet wird - es gibt keine Umkehrung der Kontrolle. Es gibt hier keine Möglichkeit, einen Scheingegenstand oder irgendeine Art von Fälschung zu injizieren. Wenn Sie den Logger in das SUT injizieren, haben Sie die Möglichkeit, den Logger zu verspotten und zu injizieren.

Die Vorteile der Verwendung von DI gegenüber der Art des in Rede stehenden statischen Methodenaufrufs gehen natürlich auch über die Testbarkeit hinaus. Überlegen Sie, was passieren würde, wenn Sie zwei verschiedene Logger in Ihrem System haben möchten, und die Option, das Anwendungsverhalten allein durch Konfiguration des Objektdiagramms zu ändern, ohne den vorhandenen Code zu bearbeiten.

Insgesamt würde ich vorschlagen, dass Sie einen DI-Ansatz versuchen, damit Sie Ihren Code später nicht als nicht testbar und unhandlich empfinden.

Sam Burns
quelle