[Bearbeiten]
Meine ursprüngliche Frage lautete: "Warum sollte man sich zwischen statisch und nicht-statisch entscheiden? Beide machen das Gleiche..."
Leider wurde sie zu einer C#-spezifischen Frage bearbeitet, was ich eigentlich vermeiden wollte.
Lassen Sie mich also einige Ergänzungen vornehmen:
Wenn ich Schnittstelle sage, meine ich nicht die C#-Schlüsselwortschnittstelle, sondern so etwas wie eine C++-Schnittstelle, wie ich sie verstehe: Eine Reihe von gut definierten Funktionen, um mit meinem Objekt zu arbeiten. Wenn ich sage, ich schwäche meine Schnittstelle, meine ich, dass ich verschiedene Funktionen (statisch/nicht statisch) habe, die dasselbe tun. Meine Schnittstelle ist nicht mehr gut definiert, wenn es verschiedene Funktionen gibt, die dasselbe tun.
Also, wie Bob der Hausmeister gepostet, kann ich eine Validate()-Funktion implementieren
Document.Validate(myDocumentObject);
sondern auch
myConcreteDocumentObject.Validate();
Um auf mein Copy()-Beispiel zurückzukommen, könnte man Copy() wie folgt implementieren
myConcreteDocument.Copy(toPath);
sondern auch
Document.Copy(myConcreteDocumentObject, toPath)
oder
Document.Copy(fromPath, toPath)
wenn ich an einen Ordner denke, der alle Dateien enthält, die zu meinem Dokument gehören (in diesem Fall bin ich nicht von einer konkreten Instanz abhängig - aber ich bin von anderen Dingen abhängig :)).
Im Allgemeinen spreche ich von statischen Methoden und nicht von statischen Klassen (sorry, wenn ich vergessen habe, dies zu erwähnen).
Aber wie Anton Gogolev schon sagte, denke ich, dass meine Dokumentenklasse kein gutes Beispiel ist und nicht gut entworfen wurde, also denke ich, dass ich einen Blick auf das Prinzip der einzigen Verantwortung werfen muss.
Ich könnte auch eine Art von ManagerClass implementieren, die mit meiner DocumentClass arbeitet:
Zum Beispiel:
myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);
oder
myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);
aber wenn ich mich auf Ansatz 1) beziehe, würde ich dazu tendieren, Objekte zu erstellen, die ihre Aufgaben selbst ausführen, anstatt andere Objekte (DocumentManager), die etwas tun con my DocumentObject.
(Ich hoffe, dies wird nicht in eine religiöse Diskussion über OOP ausarten ;)).
[/EDIT]
Alte Version:
Auf den ersten Blick scheint dies eine sehr grundsätzliche Frage zu sein, wie z.B. "wann sollte man statische Methoden verwenden und wann nicht", aber mit dieser Frage werde ich immer wieder konfrontiert (und ich habe Schwierigkeiten zu beschreiben, was das eigentliche Problem ist; vielleicht geht es nur darum, Gründe zu finden, warum man 1) oder 2) verwenden sollte.
(Obwohl ich C#-Syntax verwende, ist dies kein auf C# beschränktes Problem)
In der OOP gibt es (neben anderen) zwei Ansätze für die Arbeit mit Objekten:
1) Wenn ich möchte, dass mein Objekt etwas tut, sage ich ihm einfach, dass es das tun soll:
myConcreteObject.DoSomething();
Es ist so, als würde man mit einem Objekt sprechen.
2) Oder wenn Sie ein Fan von statischen Methoden sind:
ObjectClass.JustDoIt();
In gewisser Weise denke ich, dass sich statische Funktionen einfach besser "anfühlen". Daher neige ich dazu, statische Methoden sehr oft zu verwenden (um unabhängig von einer konkreten Instanz zu sein - Unabhängigkeit ist immer eine gute Sache).
Wenn ich also einen Kurs konzipiere, muss ich oft entscheiden, ob ich Ansatz 1) oder Ansatz 2) wähle:
Stellen Sie sich vor, Sie haben eine Klasse "Dokument", die für ein Dokument stehen soll, das in einer Datenbank gespeichert werden soll:
Ein Dokument
- besteht aus einer oder mehreren Bilddateien aus dem Dateisystem (diese werden zu den einzelnen Dokumentseiten)
- hat so etwas wie eine Bibliographie - Felder, in die der Benutzer Informationen über das Dokument einfügen kann - die in einer extra Datei gespeichert wird
- und sollte einige Operationen wie Copy(), AddPage(), RemovePage() usw. enthalten.
Jetzt stehe ich vor mehreren Möglichkeiten, diese Klasse zu erstellen:
//----- 1) non static approach/talking to objects -----
Document newDocument = new Document();
// Copy document to x (another database, for example)
newDocument.Copy(toPath);
Ich mag das: Ich sage dem Dokument, dass es sich in die Datenbank x kopieren soll, und das Objekt tut dies von selbst. Schön.
//----- 2) static approach ----------------------------
Document.Copy(myDocumentObject, toPath);
Warum nicht? Auch schön, fühlt sich sehr praktisch an...
Welche soll also umgesetzt werden? Beide? Oder den statischen Ansatz in eine Art Hilfsklasse packen? Oder wähle ich Ansatz 1) und bleibe dabei, um die Schnittstelle meiner Dokumentenklasse nicht zu schwächen?
Wenn ich über beide Ansätze nachdenke, komme ich zu dem Schluss, dass man (theoretisch) jede Funktion als statische Funktion implementieren könnte:
Class.Function(aConcreteClassObject, parameters);
aber auch nicht statisch:
aConcreteObject.DoSomething(parameters);
Um ein Beispiel aus der Praxis zu nennen:
[EDIT(Parameter fromPath hinzugefügt "Sorry, hab ich vergessen")]
//----- 2) static approach ----------------------------
File.Copy(fromPath, toPath); // .Net-Framework-like
[/EDIT]
sondern auch:
//----- 1) non static approach ------------------------
ExampeFileClass fileObject = new ExampleFileClass();
fileObject.Copy(toPath);
oder sogar (eine Art OOP-Overkill):
//----- 1) non static approach, too -------------------
fileObject.ToPath = @"C:\Test\file.txt"; // property of fileObject
fileObject.Copy(); // copy to toPath
Warum also (nicht) 1) oder (nicht) 2) verwenden?
(Ich würde mich nicht zu sehr auf das Beispiel der Dokumentenklasse konzentrieren, da es sich eher um eine allgemeine Frage über gutes Klassendesign handelt).