Ja und Nein, aber meistens Nein
Ich gehe davon aus, dass der Großteil der Konversation auf statischen oder injizierten Instanzen basiert. Niemand schlägt vor, dass die Protokollierung die SRP unterbricht, die ich annehme? Wir sprechen hauptsächlich über das "Prinzip der Abhängigkeitsinversion". Tbh Ich stimme größtenteils mit Telastyns Antwort nicht überein.
Wann ist es in Ordnung, Statik zu verwenden? Denn klar ist es manchmal okay. Die Ja-Antworten der Vorteile der Abstraktion und die Nein-Antworten weisen darauf hin, dass Sie dafür bezahlen. Einer der Gründe, warum Ihr Job schwierig ist, ist, dass Sie keine Antwort aufschreiben und auf alle Situationen anwenden können.
Nehmen:
Convert.ToInt32("1")
Ich bevorzuge dies:
private readonly IConverter _converter;
public MyClass(IConverter converter)
{
Guard.NotNull(converter)
_converter = conveter
}
....
var foo = _converter.ToInt32("1");
Warum?
Ich bin damit einverstanden, dass ich den Code umgestalten muss, wenn ich die Flexibilität benötige, den Conversion-Code auszutauschen. Ich akzeptiere, dass ich das nicht verspotten kann. Ich glaube, dass die Einfachheit und Knappheit diesen Handel wert ist.
Mit Blick auf dem anderen Ende des Spektrums, wenn IConverter
eine ist SqlConnection
, würde ich ziemlich entsetzt werden , um zu sehen , dass als statischer Aufruf. Die Gründe dafür liegen auf der Hand. Ich würde darauf hinweisen, dass ein SQLConnection
in einer Anwendung ziemlich "übergreifend" sein kann, also hätte ich diese genauen Wörter nicht verwendet.
Ist die Protokollierung eher wie ein SQLConnection
oder Convert.ToInt32
? Ich würde eher "SQLConnection" sagen.
Sie sollten sich über Logging lustig machen . Es spricht mit der Außenwelt. Wenn Convert.ToIn32
ich eine Methode mit schreibe , verwende ich sie als Werkzeug, um eine andere, separat testbare Ausgabe der Klasse zu berechnen. Ich muss nicht überprüfen, Convert
wurde korrekt aufgerufen, wenn überprüft wurde, dass "1" + "2" == "3". Protokollierung ist anders, es ist eine völlig unabhängige Ausgabe der Klasse. Ich gehe davon aus, dass es sich um eine Ausgabe handelt, die für Sie, das Support-Team und das Unternehmen von Wert ist. Ihre Klasse funktioniert nicht, wenn die Protokollierung nicht korrekt ist. Daher sollten die Komponententests nicht bestanden werden. Sie sollten testen, was Ihre Klasse protokolliert. Ich denke, das ist das Killerargument, ich könnte hier wirklich einfach aufhören.
Ich denke auch, dass sich dies wahrscheinlich ändern wird. Gute Protokollierung gibt nicht nur Zeichenfolgen aus, sondern zeigt auch, was Ihre Anwendung tut (ich bin ein großer Fan der ereignisbasierten Protokollierung). Ich habe gesehen, wie sich die grundlegende Protokollierung in ziemlich ausgefeilte Benutzeroberflächen für die Berichterstellung verwandelt hat. Es ist offensichtlich viel einfacher, in diese Richtung zu gehen, wenn Ihre Protokollierung ähnlich _logger.Log(new ApplicationStartingEvent())
und weniger ähnlich aussieht Logger.Log("Application has started")
. Man könnte argumentieren, dass dies Inventar für eine Zukunft schafft, die möglicherweise nie eintrifft. Dies ist ein Urteilsspruch, und ich denke, dass es sich lohnt.
Tatsächlich habe ich in einem meiner persönlichen Projekte eine nicht protokollierende Benutzeroberfläche erstellt, in der ich lediglich _logger
herausgefunden habe, was die Anwendung tat. Dies bedeutete, dass ich keinen Code schreiben musste, um herauszufinden, was die Anwendung tat, und ich landete in einer absolut soliden Protokollierung. Ich habe das Gefühl, dass mir diese Idee nicht in den Sinn gekommen wäre, wenn ich mich für das Protokollieren entschieden hätte, dass es einfach und unveränderlich ist.
Daher stimme ich Telastyn für den Fall der Protokollierung zu.