C# Verständnisfrage Objektorientierung

second.name

Lieutenant
Registriert
Sep. 2009
Beiträge
712
Hallo Forum,
kurze Verständnisfrage zur Objektorientierung (siehe Bild):

Den Code im Konstruktor der Klasse "ToolCall" benötige ich exakt wie abgebildet, mehrmals in der Klasse "FileToChange".

Aus diesem Grund habe ich den Code in die gezeigte Klasse "ToolCall" direkt in den Konstruktor "ausgelagert", sodass ich die Klasse nur instanziieren muss und gleich auf die benötigten Felder der Instanz zugreifen kann.

Meine Frage: Ist das objektorientiert korrekt gelöst, oder wären andere Wege sinnvoller (evtl. etwas mit Vererbung, ...)?

Danke und Gruß second.name
 

Anhänge

  • C#.PNG
    C#.PNG
    46 KB · Aufrufe: 345
Aus meiner Sicht ist das eine gute Lösung. Es ist immer erstrebenswert, wenn der Konstruktor das erzeugte Objekt direkt in einen korrekten, einsatzfähigen Zustand versetzt. Ansonsten wäre es möglich, das Objekt zu verwenden, bevor es vollständig initialisiert ist - solche Fehler vermeidet man am besten von vornherein.

Noch objektorientierter wäre es freilich, wenn der Code, der ToolCall benutzt, nicht auf dessen Felder zugreift, sondern der benötigte Code in einer Methode des ToolCall-Objekts steht. Da wir diesen Code nicht kennen, kann ich nicht beurteilen, wie sinnvoll das in diesem Fall ist. Ich sag's nur ganz allgemein :)

Mit Vererbung sollte man allgemein vorsichtig sein. Die Grundregel ist: Wenn jedes Objekt der Klasse B auch zur Klasse A gehört, dann kann man B von A erben lassen. Sonst ist das meistens keine gute Idee, und man ist mit anderen Strukturen besser dran (Beispiel: Ein Auto ist kein Motor, sondern es hat einen - daher erbt die Klasse Auto nicht von der Klasse Motor, sondern sie hat ein Feld vom Typ Motor.)
 
NullPointer schrieb:
Noch objektorientierter wäre es freilich, wenn der Code, der ToolCall benutzt, nicht auf dessen Felder zugreift, sondern der benötigte Code in einer Methode des ToolCall-Objekts steht.

Das sind jedoch keine Felder sondern Properties. Also ist es genau so, wie es sein soll.

In C# nutzt man keine Methoden wie "window.GetWidth()" sondern eben Properties "window.Width".
 
Eine Property ist effektiv auch nur ein privates Feld mit einem public Getter dran - besser als das Feld selbst public zu haben (zumindest wenn es keinen public Setter gibt, was leider immer noch viel zu oft vorkommt), aber die reine OOP-Lehre ist das nicht. Nach der soll ein Objekt nämlich nicht (nur) eine Datenkapsel sein, sondern auch Verhalten (behavior) aufweisen - wobei auf letzterem der Fokus liegt. Ein Prinzip der OOP lautet "Tell, don't ask" - anders formuliert: "Prozeduraler Code holt Informationen ein und fällt dann Entscheidungen; objektorientierter Code sagt Objekten, dass sie Dinge tun sollen." (Quelle)

Wenn du einen Getter aufrufst, sagst du dem Objekt nicht, dass es Dinge tun soll, sondern du holst Informationen ein - ein prozedurales Programmiermuster, auch wenn es mit Klassen und Objekten umgesetzt ist. Dieser Stil ist weit verbreitet und auch nicht zwangsläufig schlecht, aber er ist häufig nicht optimal: "Echt" objektorientierter Code bietet bessere Kapselung und in der Regel auch bessere Testbarkeit, lässt sich mE einfacher "sauberhalten".

Natürlich sind alle Programmierprinzipien keine Gesetze, sondern nur Richtlinien; die beste Implementation hängt immer vom Einzelfall ab. Ich würde aber in einem Fall wie hier zumindest nachprüfen, ob es Code gibt, den ich als Verhalten in die Klasse hineinziehen kann. Vielleicht stellt sich am Ende heraus, dass ich die public Getter gar nicht brauche. Vielleicht auch nicht - dann ist das halt so. (Tatsächlich führt diese Klasse ja Berechnungen aus, hat also schon ein wenig Verhalten - nur eben im Konstruktor.) Deswegen würde ich ohne Kenntnis des gesamten Codes nicht darauf pochen, dass diese Prinzipien eingehalten werden müssen - ich finde es aber wichtig, sie zu kennen, damit man sie befolgen kann, wenn es vorteilhaft ist.
 
Genau das macht doch ein Getter: "Gib mir die Daten".

Ebenso kann er Berechnungen/anderen Code ausführen, falls nötig.
 
NullPointer schrieb:
Eine Property ist effektiv auch nur ein privates Feld mit einem public Getter dran - besser als das Feld selbst public zu haben (zumindest wenn es keinen public Setter gibt, was leider immer noch viel zu oft vorkommt), aber die reine OOP-Lehre ist das nicht. Nach der soll ein Objekt nämlich nicht (nur) eine Datenkapsel sein, sondern auch Verhalten (behavior) aufweisen - wobei auf letzterem der Fokus liegt. Ein Prinzip der OOP lautet "Tell, don't ask" - anders formuliert: "Prozeduraler Code holt Informationen ein und fällt dann Entscheidungen; objektorientierter Code sagt Objekten, dass sie Dinge tun sollen." (Quelle)

Wenn du einen Getter aufrufst, sagst du dem Objekt nicht, dass es Dinge tun soll, sondern du holst Informationen ein - ein prozedurales Programmiermuster, auch wenn es mit Klassen und Objekten umgesetzt ist. Dieser Stil ist weit verbreitet und auch nicht zwangsläufig schlecht, aber er ist häufig nicht optimal: "Echt" objektorientierter Code bietet bessere Kapselung und in der Regel auch bessere Testbarkeit, lässt sich mE einfacher "sauberhalten".

Natürlich sind alle Programmierprinzipien keine Gesetze, sondern nur Richtlinien; die beste Implementation hängt immer vom Einzelfall ab. Ich würde aber in einem Fall wie hier zumindest nachprüfen, ob es Code gibt, den ich als Verhalten in die Klasse hineinziehen kann. Vielleicht stellt sich am Ende heraus, dass ich die public Getter gar nicht brauche. Vielleicht auch nicht - dann ist das halt so. (Tatsächlich führt diese Klasse ja Berechnungen aus, hat also schon ein wenig Verhalten - nur eben im Konstruktor.) Deswegen würde ich ohne Kenntnis des gesamten Codes nicht darauf pochen, dass diese Prinzipien eingehalten werden müssen - ich finde es aber wichtig, sie zu kennen, damit man sie befolgen kann, wenn es vorteilhaft ist.

Danke! Es gibt leider immer mehr Leute, die so OOP Programmieren - und wie du richtig sagst, ist es nicht OOP. Martin Fowler hat dafür auch ein Anti-Pattern gemacht bzw dieses gefunden:

https://martinfowler.com/bliki/AnemicDomainModel.html

"[...]The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters. [...]"
 
Zurück
Oben