Wir könnten ja einige Präzendenzfälle zusammentragen (wie hier den MVC-Fall), wo dann im Artikel Alternativen aufgezeigt werden. Einen ganz allgemeinen Artikel zu schreiben, ist doch sicherlich ziemlich schwierig.
Also mich würde mal ein Artikel freuen, wie man denn Klassen-Designs ohne Getter und Setter hinbekommen soll. Lese hier immer wieder im Forum, das manche Leute es ein schlechtes Design finden. Aber mich würde mal interessieren, wie das ganze denn real umgesetzt werden sollte?
Wie würde man z.B. sowas "besser" lösen können:
C/C++ Code:
class Widget
{
public:
void setModel(Model);
Model getModel();
};
C/C++ Code:
class Widget
{
public:
void setModel(Model);
Model getModel();
};
C/C++ Code:
class Widget
{
public:
void setModel(Model);
Model getModel();
};
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Hab ich da jetzt nicht wieder einen getter, der Daten zurückliefert ? Zumal reicht man jetzt doch wieder Daten rum (zumal Objekte ja auch an sich wieder Daten sind.)
ich weiß, dass dieser Thread nun schon einige Zeit her ist, aber mich interessiert ganz speziell ein bestimmtes Problem:
Ich hab eine best. Klasse, sagen wir "sprite" (wie viele das aus der Spieleprogrammierung kennen). Dieses Dingen hat eine Position in Form eines Vektors (2D oder 3D ist eigtl egal, ich nehmn ma 3D): vector<float> pos; Aufgrund von OOP- und Kapselungsprinzipien kommt es für mich nicht in Frage pos public zu machen, heißt also "private: vector<float> pos;" Jetzt muss der Benutzer ja irgendwie Einfluss auf die Position haben. Da fallen mir folgende Möglichkeiten als Lösung ein, aber für jede auch direkt ein Gegenargument, deshalb bin ich z.Z. nicht sicher wie man das Problem lösen sollte:
1.
C/C++ Code:
class sprite
{
public:
// standard getter/setter void setPos(const vector<float>& aPos);
const vector<float>& getPos() const;
};
C/C++ Code:
class sprite
{
public:
// standard getter/setter void setPos(const vector<float>& aPos);
const vector<float>& getPos() const;
};
C/C++ Code:
class sprite
{
public:
// standard getter/setter void setPos(const vector<float>& aPos);
const vector<float>& getPos() const;
};
2.
C/C++ Code:
class sprite
{
public:
// andere Namen void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir const vector<float>& where() const;
};
C/C++ Code:
class sprite
{
public:
// andere Namen void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir const vector<float>& where() const;
};
C/C++ Code:
class sprite
{
public:
// andere Namen void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir const vector<float>& where() const;
};
3.
C/C++ Code:
class sprite
{
public:
// setter als einfache Referenz
vector<float>& pos();
const vector<float>& pos() const;
};
C/C++ Code:
class sprite
{
public:
// setter als einfache Referenz
vector<float>& pos();
const vector<float>& pos() const;
};
C/C++ Code:
class sprite
{
public:
// setter als einfache Referenz
vector<float>& pos();
const vector<float>& pos() const;
};
1. ist standard, warum das hier schwer ist komm ich gleich zu
2. ist "moderner" aber differenzierter (nähert sich eher dem konzept der c++ std.bibl.)
3. ist flexibel aber enthält im Grunde keine Kapselung mehr (abgesehen von der const-überladung) und Validation (weshalb viele setter statt direkten Zugriff benutzen) ist auch nicht mehr möglich.
So, weshalb die Methode 1 "schwer" ist:
Man übergibt setPos gleich einen neuen Vektor, der die alte Position überschreibt. Manchmal will man ein Objekt aber z.b. nur in y-Richtung verschieben und die alten x- und z-Werte beibehalten. Das würde dann in so einem "Monster" gipfeln:
C/C++ Code:
obj.setPos( obj.getPos().x, y, obj.getPos().z );
C/C++ Code:
obj.setPos( obj.getPos().x, y, obj.getPos().z );
C/C++ Code:
obj.setPos( obj.getPos().x, y, obj.getPos().z );
das würde ich einem Kunden nicht gern zumuten.
Um dem zu umgehen könnte man entweder eine neue Methode einbauen, wie setPosY() die nur y-Werte setzt. Dabei würde die Klasse aber schließlich von set-Methoden überfüllt werden, die nur auf den Member pos zugreifen
Eine weitere Mögl. wäre, so etwas wie eine move-Methode einzubauen, dann könnte man für x- und z-Koordinate einfach 0 übergeben (s.O: move meint vom ausdruck her "bewegen", also eine Vektoraddition, sonst müsste man es "moveTo" nennen, wäre dann aber wieder das gleiche wie setPos). Möchte man dabei allerdings die absolute Koordinate bewegen, müsste man wieder eine Differenz aus alter und neuer Koordinate bilden:
C/C++ Code:
obj.move( 0, y - obj.getPos().y, 0 );
C/C++ Code:
obj.move( 0, y - obj.getPos().y, 0 );
C/C++ Code:
obj.move( 0, y - obj.getPos().y, 0 );
Ansonsten könnte man noch folgendermaßen argumentieren: Meine Klasse Vektor stellt sicherlich verschiedene Möglichkeiten bereit um die Position zu verschieben, ändern oder auch nur genau eine Koordinate zu verändern. Dann könnte man ja einfach eine Referenza auf pos zurückgeben, und den Benutzer mit den in vektor<> enthaltenen Funktionen arbeiten zu lassen. Das führt dann zu sowas wie
C/C++ Code:
obj.pos().y = y
C/C++ Code:
obj.pos().y = y
C/C++ Code:
obj.pos().y = y
oder
C/C++ Code:
obj.pos().y += y
C/C++ Code:
obj.pos().y += y
C/C++ Code:
obj.pos().y += y
etc., dies ist zwar flexibel und einfach, aber aus oben genannten Gründen für mich nicht möglich, da das ja einen Vollzugriff auf pos erlauben würde und dem Prinzip der Kapselung, der OOP und der Validation widerspricht (s.o.).
so, irgendwie zeigt sich da für mich keine "perfekte" Lösung. Das ganze mit dem Objekt sprite war nur ein Beispiel, würde man das abstrahieren käme man hierzu:
Wie erlaube ich möglichst nahe am Kapselungskonzept und an den Richtlinien der OOP in einer Klasse Zugriff auf ein Objekt, das in vielen (aber nicht allen) Eigenschaften/Wegen, die die Klasse dieses Objekts bereitstellt, manipuliert werden darf?
Ich hoffe ihr habt mein Problem verstanden, ich bin interessiert an allen möglichen Lösungsvorschlägen, wie ihr das in die Hand nehmen würdet (und warum ihr das so machen würdet).
Nächstes Thema anzeigen Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums
für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de
Werbekostenerstattung verdient werden kann.
Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de
enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt
(vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in
privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden.
Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere
übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.