Klassen ohne getter/setter?



  • Das wird ja hier immer verrückter! 😃 Jetzt soll ich IDs hin und her schieben, wo doch ein Objekt selbst schon eine ID hat (die Adresse). Also alles doppelt gemoppelt verwalten? Macht das alles natürlich viel wartbarer. 🤡

    Neee, also lasst mal Leute. Das ist ja alles noch schlimmer als wenn ich es weiterhin so mache, wie bisher. Überzeugt hat mich das ganze nicht. Eher abgeschreckt. Bis auf das man vielleicht seine Methoden anders bennen könnte/sollte (anstatt setSize lieber resize usw.), habe ich aus der Diskussion nicht viel für mich neues gewinnen können.

    Vielleicht haben andere etwas gewinnen können.



  • Artchi schrieb:

    Und wenn ich später ein anderes Model haben will?

    Dann brauchst du wohl zwangsläufig eine set-Methode. Die Frage ist: Brauchst du sie auch, wenn du später kein anderes Model haben willst?



  • Nein, dann natürlich nicht. Ich habe genug Klassen, wo z.B. etwas im Ctor übergeben wird, und es sich später nicht ändert. Aber das ist einfach meine pers. Designentscheidung für eine spezielle Klasse und nicht weil ich setter evil finde. Und mir geht es in diesem Thread eigentlich darum, das ich öffters im Forum lese das getter/setter evil sind, weil sie schlechtes Design sind. Also will ich eine Alternative wissen, und nicht einen speziellen Fall, weil der gerade ins Konzept passt. Und ich will keine Alternative wo ich Mehraufwand habe (siehe ID).

    Denn ganz ehrlich? Ich habe mir Sorgen gemacht, das ich irgendwas verpasst habe. 😃 Deshalb auch die ernsthafte (!) Anfrage nach einem solchen Artikel.



  • Artchi schrieb:

    Am Ende geht es hier anscheinend nur darum, wie die Funktion heißt? Soll heißen, die Anti-Setter-Getter-Fraktion stört sich nur am Funktionsnamen?

    Nein, ist bei mir jedenfalls nicht so.

    Beispiel MVC:

    class Widget : public IBlaObserver
    {
    public:
        Widget()
        {
            Model::addObserver( this );
        }
    
        ~Widget()
        {
            Model::removeOberserver( this );
        }
    };
    

    Es kann sein, dass ich den Fall nur noch nicht hatte, aber wozu braucht man bei MVC ein wechselndes Modell? Oder wann würde es Sinn machen, dass verschiedene View-Elemente auf verschiedenen Modellen arbeiten? Und wenn ein Modell-Wechsel stattfindet, wieso sollte der Wechsel im View stattfinden und nicht im Modell oder einem Controller, der sich nach außen hin wie ein Modell gibt?

    Ups, hatte den Beitrag vor ~2 Stunden angefangen, mir kam dann was dazwischen, wollte die Diskussion nicht wieder anheizen.



  • EDIT: Beitrag auf den es sich bezog ist out of date.



  • Knuddlbaer schrieb:

    Apollon schrieb:

    Knuddlbaer schrieb:

    und wie kommt man an die nötigen Daten rann ?

    Hoe? Man hat doch freien Zugriff drauf... Ach! Du meinst von aussen?! Nochmal: man reicht nicht Daten rum, sondern Objekte.

    Davon das Du Deine Aussage wiederholst, wird sie nicht besser. Was fange ich mit einem Objekt an, das ich übergeben bekommen habe ?

    Mit doofen Fragen wirst Du sie aber auch nicht schlechter machen.

    Knuddlbaer schrieb:

    Was bringt mir ein Objekt, das Berechnungen vornimmt wenn man die Daten nicht verwenden kann ?

    var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
    


  • 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.



  • Artchi schrieb:

    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:

    class Widget
    {
        public:
           void setModel(Model);
           Model getModel();
    };
    

    http://www.pragprog.com/articles/tell-dont-ask



  • Wenn ich einfach nur irgendwo ne Schriftgröße abfragen und ändern will, wie soll man den sowas ohne getter und setter machen?



  • 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.)



  • Hi,

    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.

    class sprite 
    {
    public:
         // standard getter/setter
         void setPos(const vector<float>& aPos);
         const vector<float>& getPos() const;
    };
    

    2.

    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.

    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:
    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
    void setPos(const vector<float>& aPos);
    void setPosX(float aX);
    void setPosY(float aY);
    void setPosZ(float aZ);
    
    • 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:
    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
    obj.pos().y = y
    

    oder

    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).

    Vielen Dank! 🙂

    PS: ggf kann das Thema auch abgespalten werden


Anmelden zum Antworten