Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].
Deine (dot) Meinung dazu dürfte, wenn ich mich nicht irre, sein, dass man grundsätzlich nur einen Getter oder nur einen Setter braucht, da es andernfalls häufig schlechtes Design dazu führt, beides zu haben.
Mit Eigenschaften meine ich Felder einer Klasse.
Programme bestehen doch nunmal aus Daten und Logik.
Ich denke bestes Beispiel ist doch wohl Darstellung von Daten. Wenn du getrennte Schichten für Darstellung und Logik hast, dann muss die Darstellung die Daten aus der Logik-Schicht bekommen. Wie soll das denn bitte ohne Getter gehen?! (Ich vernachlässige jetzt mal aus Einfachsheitsgründen Darstellungsobjekte, bspw. ViewModels).
@dot:
Was ist denn mit sowas wie SetPosition oder SetColor für irgendwelche grafischen Objekte? Oder SetCaption für ein GUI-Element?
Wie würdest du das anders machen? Klar könnte man SetPosition auch MoveTo nennen (oder so ähnlich), aber im Kern bliebe es dasselbe.
Warum Getter und Setter:
Kapselung von zusätzlicher Funktionalität. z.B. Validierung oder nachfolgender Mechanismen. + Erweiterbarkeit!
Verstecken des Types durch Interfaces.
konsistente Interfaces, unabhängig von der Implementierung.
Debugging
externe Libs, die automatisiert Getter und Setter verwenden
Funktion überschreiben
Ich bin auch grundsätzlich gegen die Philosophie, Programmierer durch die Sprache disziplinieren zu wollen.
Dito.
Das habe ich z.B. oft gebraucht, wenn ich Strukturen direkt aus einer Datei lesen wollte.
Da aber der Compiler bei Optimierung Byte-Alignments nach belieben einbauen kann, sollte das dadurch verhindert werden.
Ich persönlich erachte u.A. Interfaces - die erzwungener Maßen keine Funktions-Implementierungen haben können - als eher unwichtig in einer Sprache.
Wer ein reines Interface habe will, der soll eine reine abstrakte Klasse schreiben - das geht mit meiner Sprache auch, so wie in C++ mit "virtual ... = 0",
bei mir heißt es dann halt "abstract ...".
Ich habe genau deshalb Reference-Counting ewählt, weil das schon in C++11 und boost implementiert ist.
Außerdem halte ich Garbage-Collection für ineffizienter (zumindest was die Leistung betrifft).
In Objective-C z.B. wird GC zwar generell unterstützt, für iPhone/ iPad ist es aber nicht verfügbar.
Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von »dot« (16.01.2014, 15:52)
Na moment du bist der Meinung, dass Getter und Setter schlechtes Design sind, benutzt aber selber mindestens einen?
Im Kern hast du Recht, pauschalisierst aber zuviel. Ich denke man sollte Getter/Setter vermeiden, wenn es geht, aber in der Praxis geht es eben oft nicht. Das ist dann aber auch kein Zeichen von schlechtem Design, sondern einfach notwendig.
Die Tween Engine setzt Getter sowie Setter voraus um ein Objekt über die Zeit zu manipulieren. Heißt du musst Getter und Setter bereitstellen um ein definiertes Attribut zu verändern.
Selbst dein Brush hat doch wohl mehr als einen Getter und Setter?!
Ich glaube, du siehst da einige Teile der theoretischen Informatik etwas zu sehr mit Tunnelblick. Ich hab in meiner ganzen Laufbahn noch nie gehört oder Erfahren, dass sowas schlechtes Design ist.
Kapselung heißt doch auch nur, dass die Funktionalität und Fähigkeiten (== Eigenschaften == Felder) nicht direkt publiziert werden sollten, dass die Kontroller innerhalb des Objektes bleibt. Aber genau das wird doch durch Getter und Setter gekapselt. Und das ganze in einem Getter/Setter zu tun und immer das in eine Struktur oder Subklassen zu tun ist doch teilweise total overengineered.
Warum müssen eigentlich immer direkt so Grundsatzdiskussionen angezettelt werden? Vor allem denke ich haben solche Diskussionen doch recht wenig mit der Praxis zu tun. In der Industrie muss vieles eben nun mal quick and dirty gehen. Zeit ist eben Geld. So habe ich es zumindest teilweise erlebt und so sieht es auch bei Bekannten von mir aus. Ob man das jetzt unterstützen möchte ist eine andere Sache. Aber vor allem um so Dinge wie Code Design und was ist jetzt besser im OOP Sinne als etwas anderes, das sind Punkte da kann man sich im Prinzip beliebig lange drüber streiten und kommt zu keinem Ergebnis.
Dann können wir als nächstes darüber sprechen ob die Sprache low level Dinge unterstützen soll um möglichst performant entwickeln zu können oder nicht [...]
dot dir ging es jetzt hier ja um Getter und Setter und darum dass diese oft ein Anzeichen für schlechtes Design sind.
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »dot« (16.01.2014, 17:38)
Zitat von »LetsGo«
Die Tween Engine setzt Getter sowie Setter voraus um ein Objekt über die Zeit zu manipulieren. Heißt du musst Getter und Setter bereitstellen um ein definiertes Attribut zu verändern.
Und dass es in der Praxis gemacht wird, heißt für dich, dass es in der Praxis nicht besser geht und man daher am besten vor dem Problem kapituliert!?
OK und dein konkreter Lösungsansatz wäre?
Zitat von »LetsGo«
Die Tween Engine setzt Getter sowie Setter voraus um ein Objekt über die Zeit zu manipulieren. Heißt du musst Getter und Setter bereitstellen um ein definiertes Attribut zu verändern.
Und dass es in der Praxis gemacht wird, heißt für dich, dass es in der Praxis nicht besser geht und man daher am besten vor dem Problem kapituliert!?
OK und dein konkreter Lösungsansatz wäre?
Sauberer wäre es meiner Meinung nach, wenn man nicht manuell die [Position, Farbe, Größe, ...] etc. übertragen müsste, sondern dem [Zielelement] die Quelle für seine [Eigenschaft] mitteilen könnte. Sobald diese Datenquelle [...] dann darüber informiert, dass sich die gewünschte [Eigenschaft] geändert hat, speichert das [Element] diese.
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Sacaldur« (16.01.2014, 18:52)
Ich kenn die Engine nicht und ich müsste mir diese wohl erstmal im Detail anschauen. Eine Beobachtung kann ich basierend auf deiner Beschreibung allerdings machen: Die Position von Objekten ergibt sich in der Regel wohl aus der Spiellogik. Eigentlich müsste also lediglich die Spiellogik die Objekte bewegen, niemals muss aber deren Position abgefragt werden. Die Engine würde idealerweise intern gar keine explizite Position speichern, sondern lediglich was auch immer für Daten für die Darstellung des Objektes benötigt werden (also z.B. eine Matrix) und keinen Getter anbieten, um Stateduplication zu vermeiden. Das Vorhandensein eines Getters verführt in dem Fall nur dazu, dass die Spiellogik die Engine-Objekte als Datencontainer missbraucht und nun plötzlich alles in beide Richtungen synchron gehalten werden muss...
Aber ich stimme zu, wenn dann sollten wir diese Diskussion nun besser in dem von dir verlinkten Thread fortführen...
Die TweenEngine hat aber gar keine Ahnung davon.
Die weiß nur ich hab Attribut A und soll das in der Zeit X mit einem bestimmten Interpolations-verfahren, in einer bestimmten Zeit, einem Wert B zuweisen.
Klar wird die Spiellogik den Tween(z.B Alphafading/Positionsänderung/Farbe) anstoßen, aber um die Engine zu verwenden muss sich eben Getter und Setter bereitstellen, denn es gibt keine Alternative, außer die Funktionalität im Spieleobjekt selbst zu implementieren.
[unnötiges Zitat entfernt]
Zitat von »LetsGo«
Die Tween Engine setzt Getter sowie Setter voraus um ein Objekt über die Zeit zu manipulieren. Heißt du musst Getter und Setter bereitstellen um ein definiertes Attribut zu verändern.
Und dass es in der Praxis gemacht wird, heißt für dich, dass es in der Praxis nicht besser geht und man daher am besten vor dem Problem kapituliert!?
OK und dein konkreter Lösungsansatz wäre?
Eine Möglichkeit schließt eine Sache ein, die ich bereits erwähnt hatte (für den aktuellen Kontext leicht angepasst):
Sauberer wäre es meiner Meinung nach, wenn man nicht manuell die [Position, Farbe, Größe, ...] etc. übertragen müsste, sondern dem [Zielelement] die Quelle für seine [Eigenschaft] mitteilen könnte. Sobald diese Datenquelle [...] dann darüber informiert, dass sich die gewünschte [Eigenschaft] geändert hat, speichert das [Element] diese.
Die Quelle der Eigenschaft (z. B. der Farbe) könnte nicht nur auf normale Objekte und deren Veränderungen reagieren und den Wert direkt durchreichen, sondern auch anhand von bestimmten Bedingungen eine Interpolation durchführen (oder andere Arten der Umrechnung anwenden, wie ich ursprünglich bereits ein Beispiel gebracht habe).
Sollte man die Datenquelle im Konstruktor übergeben können, sind keine Getter und Setter notwendig.
Anderes Bsp:
Ich hab ein Button, der erzeugt bei Click ein Event. Dem Event ist eine VerursacherObjekt zugeordnet (der Button.) Im Zuge der Eventbehandlung(Dispatcher) wird dem Event dynamisch ein ZielObjekt(set) zugeordnet, wenn es bisher noch nicht bekannt war(get ==null). Ein Event ist abstrakt, es kann auch durch etwas anderes entstanden sein bei dem schon ein Zielobjekt bekannt war. Angekommen am Evenhandler, der für eben dieses Event zuständig ist werden sowohl Zielobjekt als auch Verursacherobjekt benötigt (get). (Der Button(Verursacher) wird ausgeblendet und das Zielobjekt tut irgendwas).
Immer dann wenn Ein Objekt eine Kette von Handlern (Consumerchain)oder sonstwas durchläuft (die Hierarchie einer Anwendung nach oben geht) muss es evtl mit Informationen, die zuvor nicht bekannt waren, angereichert werden. Da die jeweilige Ebene aber nicht weiß, ob die Information schon vorher bekannt war muss ich eben schauen, ob das der Fall ist oder nicht. (Getter/Setter)
Mag in Spielen vllt. nicht so häufig vorkommen, aber in verteilten Systemen ist sowas sehr sehr oft der Fall. (z.B. JavaEE).
BTW: Jemand sollte das abspalten
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].
Werbeanzeige