Die widersprüchlichen Ratschläge, die Sie gelesen haben, sind alle in gewisser Weise sinnvoll, aber sie alle machen (unterschiedliche) Annahmen oder formulieren Dinge mehrdeutig. Es ist eine dieser Arten von Unterscheidungen, die "dasselbe mit verschiedenen Worten sagen".
Eine Methode sollte nur statisch sein, wenn sie einen Status nicht ändert
Beachten Sie die Mehrdeutigkeit von "Status ändern". Das folgende Beispiel verstößt (buchstäblich) gegen diese Regel, bewahrt jedoch den (bildlichen) Geist der Regel:
public static void SetUserNameToBob(User u)
{
u.Name = "Bob";
}
Dadurch wird der Status des User
Objekts geändert, sodass tatsächlich ein Status geändert wird.
Allerdings ist diese Methode nicht verläßt auf einem bestimmten internen Zustand , um seine eigenen logischen Fluss zu entscheiden (zB u.Name = currentlySelectedDefaultName()
wäre ein Verstoß als der gewählte Name ein ausgewählter Zustand ist). Und ich denke, das ist gemeint: Kein interner Zustand wird geändert.
[Eine Methode sollte nur statisch sein, wenn] ihr Ergebnis nur von den ihr zur Verfügung gestellten Parametern abhängt
Schauen Sie sich den vorherigen Artikel an, dieser sagt so ziemlich dasselbe. Was es bedeutet ist, dass dies:
public static string currentlySelectedDefaultName;
public static void SetUserNameToBob(User u)
{
u.Name = currentlySelectedDefaultName;
}
sollte nicht statisch sein, da der "aktuelle Standard" -Name ein Status ist und daher keine globale Variable / Methode sein sollte.
Überlegen Sie, was passiert, wenn zwei separate Threads ausgeführt werden: Einer möchte standardmäßig "Bob", der andere standardmäßig "Jim". Sie werden am Ende um den Wert streiten, was zu massiven Debugging-Problemen und unerwartetem Verhalten führen kann.
Wenn jedoch jeder Thread ein eigenes DefaultNameSetter
Objekt hat, kämpfen sie nicht um dieselbe Ressource.
Die am häufigsten gewählte Antwort in diesem Beitrag besagt jedoch, dass nach Möglichkeit statische Methoden verwendet werden sollten.
Dies ist eine Art Durchsetzung einer Regel durch Versuch / Misserfolg. Können wir diese Methode auf statisch setzen?
- Ja
=>
gut! Lass es so wie es ist!
- Nein
=>
Dies beweist, dass der Code irgendwo auf einem nicht statischen Wert basiert und daher nicht statisch gemacht werden sollte.
Um Jeff Goldblum im Jurassic Park indirekt zu zitieren , sollten Sie nicht die Notwendigkeit argumentieren , etwas zu tun, indem Sie nur beweisen, dass es möglich ist .
Auch hier ist der Ansatz nicht unbedingt (oder immer) falsch, aber er geht blind davon aus, dass Methoden bereits so zustandsunabhängig wie logisch möglich geschrieben sind, was einfach nicht der Fall ist.
Selbst wenn Sie diesen methodischen Ansatz abonnieren, können Sie ihn nur anwenden, wenn sich ein Projekt nicht mehr in der Entwicklung befindet. Wenn sich das Projekt noch in der Entwicklung befindet, können aktuelle Methoden Platzhalter für die zukünftige Implementierung sein. Es könnte möglich sein, Foo()
heute statisch zu machen , aber nicht morgen, wenn die zustandsabhängige Logik einfach noch nicht implementiert wurde.
Viele der Antworten in diesem Beitrag besagen, dass man alles tun sollte, was am logischsten ist.
Nun, sie sind nicht falsch; Aber ist das nicht nur eine kleine Umformulierung von "Mach das Richtige"? Das ist kein wirklich hilfreicher Rat, es sei denn, Sie wissen bereits, wann Sie Statik verwenden und wann Sie sie vermeiden müssen. Es ist ein Haken 22.
Wann sollten Sie Statik verwenden?
Wie Sie bemerkt haben, sind sich nicht alle einig über die Regel oder zumindest darüber, wie die Regel formuliert werden soll. Ich werde hier einen weiteren Versuch hinzufügen, aber sei dir bewusst, dass dies effektiv einen anderen Standard schafft :
Merk dir das.
Statik sind universelle Wahrheiten.
Das ist der Zweck eines globalen Namespace: Dinge, die auf der gesamten Anwendungsschicht korrekt sind.
Hier gibt es ein Argument für einen rutschigen Hang. Einige Beispiele:
var myConfigKey = ConfigurationManager.AppSettings["myConfigKey"];
Dies ist ein sehr klares Beispiel. Die Anwendungskonfiguration impliziert von Natur aus, dass die Konfiguration für die Anwendung global ist, und daher ist eine statis-Methode erforderlich.
bool datesOverlap = DateHelper.HasOverlap(myDateA_Start, myDateA_End, myDateB_Start, myDateB_End);
Diese Methode ist allgemein korrekt. Es ist egal, welche Daten Sie vergleichen. Die Methode kümmert sich nicht um die Bedeutung der Daten. Ob es sich um Beschäftigungsdaten, Vertragsdaten usw. handelt, spielt für den Algorithmus der Methode keine Rolle.
Beachten Sie die semantische Ähnlichkeit zwischen kontextbezogen und zustandsgesteuert . Beide Sortierungen beziehen sich auf einen "nicht universellen" Zustand. Dies beweist, dass Kontextunterschiede daher zustandsabhängig sind und nicht geeignet sind, statisch gemacht zu werden.
var newPersonObject = Person.Create();
Dies ist eine universelle Wahrheit. Der gleiche Erstellungsprozess wird in der gesamten Anwendung verwendet.
Diese Linie kann jedoch unscharf werden:
var newManager = Person.CreateManager();
var newJanitor = Person.CreateJanitor();
Aus technischer Sicht hat sich nichts geändert. Manager (und Hausmeister) werden in der gesamten Anwendung auf dieselbe Weise erstellt. Dies hat jedoch auf subtile Weise einen Staat (Manager / Hausmeister) geschaffen, der langsam, aber stetig davon ablenkt, wie universell die Wahrheit wirklich ist.
Kann es gemacht werden? Aus technischer Sicht; ja .
Sollte es getan werden? Dabei geht es darum, ob Sie das reine Prinzip argumentieren oder berücksichtigen, dass Kompromisse eingegangen werden müssen, um nicht sinnlos nach logischer Perfektion zu streben. Ich würde also sagen, wenn es kein größeres Problem schafft, als das Problem zu lösen beabsichtigt .
Mit der Erweiterung der Optionen (Manager, Hausmeister, Buchhalter, Verkäufer usw.) wächst das Problem. Für ein ausreichend großes Problem ist ein Fabrikmuster wünschenswert.
Wenn Sie nur zwei Optionen haben und keinen Grund zu der Annahme haben, dass die Liste der Optionen erweitert wird, können Sie argumentieren, dass die statischen Erstellungsmethoden ausreichen. Einige mögen anderer Meinung sein, und ich verstehe auch ihren Standpunkt. Aber ich neige dazu, praktisch und nicht übermäßig perfektionistisch zu sein.