Was gilt als gutes OOP ?
-
cooky451 schrieb:
Halte ich außerdem für extrem sinnlos. Das macht's irgendwie selten übersichtlicher. Wenn der "Nutzer" der Klasse eh vollen Zugriff auf eine Variable haben soll, warum dann nicht gleich public machen?
Der Sinn darin ist, wenn du irgendwann merkst, dass die Variablen eben doch noch so direkt gesetzt werden sollen, sondern du z.B bei einer Zahl noch den Bereich überprüfen willst o.ä. Dann kannst du das machen, ohne dass der Nutzer der Klasse das mitbekommt.
Wenn möglich sollte man natürlich eine solch direkte Veränderung der Klasse verhindern, aber wenn überhaupt, aber wenn, dann sollte man sie durch getter/setter schützen.
Ich habe z.B im Moment in einem Projekt einige Klassen, die praktisch nur aus setter/getter bestehen, da sie Daten aggregieren, aber dennoch beim setzen einiges an processing benötigen.
protected Member Variablen haben ähnliche Probleme, wie public Variablen und sollte sie daher auch eher vermeiden.
-
drakon schrieb:
Der Sinn darin ist, wenn du irgendwann merkst, dass die Variablen eben doch noch so direkt gesetzt werden sollen,
Na gut ok, ist bei mir noch nie vorgekommen

drakon schrieb:
protected Member Variablen haben ähnliche Probleme, wie public Variablen und sollte sie daher auch eher vermeiden.
Kannst du das näher beschreiben? Ich verstehe nicht ganz, was gegen protected sprechen soll.
-
cooky451 schrieb:
drakon schrieb:
protected Member Variablen haben ähnliche Probleme, wie public Variablen und sollte sie daher auch eher vermeiden.
Kannst du das näher beschreiben? Ich verstehe nicht ganz, was gegen protected sprechen soll.
Abgeleitete Klassen können die Member einfach verändern? Wenn die Variablen const sind dann kannst du sie protected machen da sie dann sowieso in der Basisklasse initialisiert werden müssen, ansonsten isses aber in der Regel extrem hässlich. Wobei ich sowieso soweit gehen und sagen würde dass man mit Vererbung generell sparsam sein sollte, vor allem wenn es um nicht abstrakte Basen geht. Meistens kommt man einfach mit Interfaces zurecht und das resultierende Design ist viel flexibler.
-
cooky451 schrieb:
drakon schrieb:
protected Member Variablen haben ähnliche Probleme, wie public Variablen und sollte sie daher auch eher vermeiden.
Kannst du das näher beschreiben? Ich verstehe nicht ganz, was gegen protected sprechen soll.
Naja, eben gesetzt der Fall, dass du keinen trivialen getter/setter hast. Kommt dann einer und meint, dass er von der Klasse erben will und macht da seine Erweiterung. Er sieht, dass die Variable protected ist und verändert sie dann so, wie er mag. Dann ruft er eine Funktion der Basisklasse auf und die geht davon aus, dass die Invariante für diese Variable (z.B > 10 für ein int) gegeben ist (da er ja alle Zugriffe durch den setter kontrolliert) und das ganze geht dann kaputt.
Wenn du also eine Variable protected machst, dann kannst du sie eigentlich auch gleich public machen, dann achtest du wenigstens darauf, dass die Variable irgendeinen Zustand haben kann.
-
drakon schrieb:
Er sieht, dass die Variable protected ist und verändert sie dann so, wie er mag.
Sein Fehler

Aber ok, verstehe was du meinst.
-
Kann man also generell sagen, dass es nicht so wichtig ist ? Bzw. dass es schlicht weg auf die Situation an kommt und sowohl private als auch public gleich oft benutzt werden ?
Dachte halt bis jetzt immer, man sollte versuchen die Variablen public zu machen. Nur wenns unbedingt nötig ist public.
-
cooky451 schrieb:
<<OOP Hasser>>
Nicht-Kenner triffts besser. Welchen Vorteil Getter und Setter haben, ist wohl eines der ersten Dinge, die einem bei OOP erklärt werden.
cooky451 schrieb:
Ich würde vor allem möglichst alles erstmal protected machen, private nutze ich eher selten.
Finde ich eine schlechte Idee. Man sollte die Kapselung so stark wie möglich gestalten, also standardmässig
private.protectedbei Membervariablen habe ich fast nie.
-
Der Artikel enthält etwas viel Bla Bla, aber in gewissen Punkten hat er Recht.
Why getter and setter methods are evil schrieb:
Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details.
Zu einem gewissen Teil stimmt das, vor allem wenn man Member 1:1 und präventiv auf entsprechende Getter/Setter abbildet. Auf gewisse Eigenschaften muss vor aussen gar nicht zugegriffen werden, oder der Zugriff muss nur lesend oder schreibend erfolgen, oder indirekt durch eine Aktion. Allerdings gibt es sehr wohl Situationen, in denen man Eigenschaften der Klasse direkt ändern muss, ganz ohne Setter/Getter kommt man nicht vernünftig aus.
GutesOOP? schrieb:
Kann man also generell sagen, dass es nicht so wichtig ist ? Bzw. dass es schlicht weg auf die Situation an kommt und sowohl private als auch public gleich oft benutzt werden ?
Nein,
publicsollte sparsam eingesetzt werden. Halte Schnittstellen schmal. Gerade in C++ hast du im Gegensatz zu Java die Möglichkeit, die Funktionalität einer Klasse durch freie Funktionen zu erweitern. Nutze sie.
-
Nexus schrieb:
cooky451 schrieb:
<<OOP Hasser>>
Nicht-Kenner triffts besser. Welchen Vorteil Getter und Setter haben, ist wohl eines der ersten Dinge, die einem bei OOP erklärt werden.
Ja. Und erst recht spät lernt man, sie korrekt zu meiden.
-
Nexus schrieb:
cooky451 schrieb:
<<OOP Hasser>>
Nicht-Kenner triffts besser.
War damit gemeint, wollte mich nur nicht gleich vor allen outen.
Ich verstehe den Sinn hinter Gettern/Settern schon, aber halt nur wenn sie mehr machen als "m_x = x" und "return m_x".
-
volkard schrieb:
Ja. Und erst recht spät lernt man, sie korrekt zu meiden.
Das ist ein generelles Problem, das der OOP-Hype mit sich bringen kann. Andere Beispiele sind der übermässige Einsatz von Vererbung, das Immer-polymorph-Machen von Basisklassen oder das Vermeiden globaler Funktionen ("nicht objektorientiert, weil nicht in Klasse").
Du bringst es gut auf den Punkt: Schwieriger als die korrekte Verwendung ist die korrekte Nicht-Verwendung

cooky451 schrieb:
Ich verstehe den Sinn hinter Gettern/Settern schon, aber halt nur wenn sie mehr machen als "m_x = x" und "return m_x".
Auch solche Getter/Setter können Sinn machen, besonders weil man jederzeit die Möglichkeit hat, mehr Funktionalität zu implementieren, ohne User-Code zu beeinträchtigen.
-
Was haben Getter und Setter mit OOP zu tun?
-
Was machen die die keine Getter und Setter wollen, bei folgendem Beispiel?
Bei einem 3D-Modellierungs-Programm hat man Objekte (Boxen, Linien...), denen kann man eigentlich auch immer Namen geben. Dazu gibt es in irgendeinem Editor, in dem auch noch alles mögliche andere eingestellt werden kann, auch ein Feld für den Namen. Wenn jetzt ein User dort einen Namen eingibt, ruft ihr dann nicht object.setName(...) auf? Was dann?
-
butterbeidiefische schrieb:
Dazu gibt es in irgendeinem Editor, in dem auch noch alles mögliche andere eingestellt werden kann, auch ein Feld für den Namen. Wenn jetzt ein User dort einen Namen eingibt, ruft ihr dann nicht object.setName(...) auf? Was dann?
Doch, da schon.
Aber im Spiel wird's vermutlich kein setName geben, sondern im Konstruktor wird der Name geladen und nie mehr verändert.
-
Kann es sein, dass die Getter/Setter-Gegner davon ausgehen, dass man total dämlich programmiert? Also anstatt vector.push_back irgendwie getSize, getArrayPointer, ... setArrayPointer, setSize(++size), setValue...
-
butterbeidiefische schrieb:
object.setName(...) auf? Was dann?
Noe, ich mach das mit object.name = "blubb"

-
cooky451 schrieb:
butterbeidiefische schrieb:
object.setName(...) auf? Was dann?
Noe, ich mach das mit object.name = "blubb"

Was dumm wäre, wenn du auch noch etwas anderes machen willst, z.B. Callbacks für nameChanged.
-
Sorry aber dein Post kam irgendwie so sinnlos, da musste das einfach sein

-
Implementierungsdetails einer Klasse privat zu machen gehört nun zu den absoluten Basics von OOP. Nur weil du eine Klasse schreibst und vor Daten ein private schreibst,programmierst du noch lange nicht objektorientiert.
Gute OOP fördert die Erweiterbarkeit, Flexibilität und Wartbarkeit von Software durch Abstraktion, Kapselung und Reduzieren von Abhängigkeiten (das Verhindern einer Abhängigkeit zu irgendeiner bestimmten Variable gehört da als einfachstes Mittel dazu). Als Einstieg in gute OOP kann ich die sog. SOLID Prinzipien als Lesestoff empfehlen (google solid oop).
Über den Sinn und Unsinn von Getter/Setter wird hier ja fast wöchentlich erneut diskutiert, ich weiß gar nicht warum. Daten von nicht trivialen Typen sind privat und wenn die niemanden was angehen schreibt ich keine Getter/Setter. Man schreibt grundsätzlich nichts was man nicht braucht. Und wenn man so einfache Daten wie einen Namen manipulieren oder auf den Bildschirm schreiben will, dann gibt es dafür halt eine öffentliche Schnittstelle. Man könnte zwar auch die Klasse selber auf den Bildschirm schreiben lassen, aber die sich daraus ergebene Abhängigkeit zu Ein-/Ausgabe Techniken ist viel schlimmer als eine zusätzliche Schnittstelle. Mitconsthat man in C++ ja auch eine schöne Kontrolle über diese Zugriffe.
-
Nexus schrieb:
cooky451 schrieb:
<<OOP Hasser>>
Nicht-Kenner triffts besser. Welchen Vorteil Getter und Setter haben, ist wohl eines der ersten Dinge, die einem bei OOP erklärt werden.
Leider wird selbst (oder gerade?) an Unis auch nicht viel mehr gelehrt. Es gibt zu viele Entwickler die Getter und Setter mit Kapselung gleich setzen und null Ahnung haben wieviel mehr hinter diesem Begriff steckt.
Dazu wird noch alles in eine Klassenhierarchie gestopft und schon hat man ein tolles OO-System

Ich setze Getter/Setter (bzw. Properties in C#) nur für relativ unkritische Datenfelder ein. Zu viel Logik in den Xettern ist verwirrend und verursacht jede Menge klasseninterne Abhängigkeiten. Dann packe ich das lieber in eine Methode mit sprechendem Namen.