Gegenteil von Setter-Methoden

Dieses Thema Gegenteil von Setter-Methoden im Forum "Java Basics - Anfänger-Themen" wurde erstellt von propra, 11. Jan. 2012.

Thema: Gegenteil von Setter-Methoden Hallo zusammen, manchmal benötige eine Variable, um anzuzeigen, ob etwas gesetzt wurde. Z.B., ob etwas ausgewählt...

  1. Hallo zusammen,

    manchmal benötige eine Variable, um anzuzeigen, ob etwas gesetzt wurde. Z.B., ob etwas ausgewählt wurde.
    Dann muss ich, wenn ich die Auswahl aufheben möchte, natürlich auch diesen Wert löschen.
    Also kommt so etwas hier heraus:
    Code (Java):
    public void setIsSomethingSet(boolean bool) {
            somethingToSet = bool;
        }
    Jetzt empfinde ich diese Konstruktion als komisch und das ist eigentlich oft ein Zeichen dafür, dass es falsch ist bzw. cleverer gelöst werden kann.
    Kann mir jemand verraten, wie man solche Situationen am besten löst?

    Vielen Dank
     
  2. Schau mal hier --> (hier klicken!)
    Dort wirst du fündig!
  3. Sym
    Sym
    Code (Java):
    public void setSomethingToSet(boolean bool) {
            somethingToSet = bool;
        }
    Das is lässt man in der Regel weg. :)
     
  4. grundsätzlich besteht natürlich auch die Möglichkeit, in der Variablen selbst das Nicht-Gesetzt-Seit auszudrücken,
    durch null-Wert oder eine bestimmte Konstante,
    für primitive Datentypen sicherlich schwieriger, da gibts noch 0 oder -1, bei boolean wirds haarig ;)
     
  5. Wenns dir nur darum geht die Variable somethingToSet "umzudrehen" dann könnte man auch sowas machen:
    Code (Java):
    public void flipSomething() {
        something = !something;
    }
    Dann muss der Aufrufer sich nicht darum kümmern den aktuellen Status zu holen.

    Ansonsten, siehe Syms antwort. Das ist dann nen normaler setter für nen boolean wert.
     
  6. Bei Booleans bietet es sich an, statt der setter-Syntax einfac zwei Methoden enable und disable zu bauen. Etwa so:
    Code (Java):

    public class MyClas {

      private boolean myBoolean;

      /* Setter und Getter nach Bean-Konvention */
      public void setMyBoolean(final boolean theBoolean) {
        this.myBoolean = theBoolean;
      }

      public boolean getMyBoolean() {
        return this.myBoolean;
      }

      /* Bei booleans darf der "getter" auch mit "is" beginnen, also: */
      public boolean isMyBoolean() {
        return this.myBoolean;
      }

      /* Und nun die Schalter-Methoden */
      public void enableMyBoolean() {
         this.myBoolean = true;
      }

      public void disableMyBoolean() {
        this.myBoolean = false;
      }

      public void flipMyBoolean() {
        this.myBoolean = !this.myBoolean;
      }

    }
     
     
  7. @nillehammer
    6 methoden fuer ein boolean ?!

    mhm

    Code (Java):

    public class MyClas {
      private boolean myBoolean;

      public boolean isMyBoolean() {
        return this.myBoolean;
      }

      public void setMyBoolean(final boolean theBoolean) {
        this.myBoolean = theBoolean;
      }
     
    mehr brauchts nicht.

    selbst bei flipMyBoolean bin ich nicht so ueberzeugt, da der aufrufer keine ahnung hat in welchen Zustand sich myBoolean befindet und es gewiss zu code ala
    [code=Java]
    if (myClass.isMyBoolean()) {
    myClass.flipMyBoolean();
    }
    [/code]
    kommt (bzw mit der negation).[/code]
     
  8. Ja, wenns zu so nem Code kommt, dann ist nen normaler setter sicherlich die bessere Wahl ;)
    Es kommt halt wie gesagt drauf an in welchem Kontext man den boolean nutzt. Du hast aber recht, in der Regel tuts nen gewöhnlicher setter.
     
  9. propra hat nach möglichen Alternativen zu der normalen Setter-Syntax gefragt. Die hab ich genannt. Was er davon benutzt (sicher nicht alles), kann er sich dann selbst aussuchen. Und flips hab ich im Zusammenhang mit GUI-Elementen, die man auf- und zuklappen kann schon selbst oft benutzt. Da ist es mir nämlich egal, wie der aktuelle Zustand ist, ich will einfach, dass er sich ändert.
     
  10. Warum kümmerst du dich um die Verwaltung des Wertes (gesetzt/ nicht gesetzt) nicht in der set-Funktionen deines Objektes?
    Wenn du z.B. eine Variable
    Code (Text):
    int groesse
    hast und eine
    Code (Text):
    boolean bSet = false
    dann schreibst du
    Code (Java):

    void setGroesse(int groesse) {
        this.groesse = groesse;
        this.bSet = true;
    }

    boolean isSet() {return this.bSet;}
    void disable() {this.bSet = false;}
     
    wenn du dann in einer Auswahl eine andere Option auswählst, musst du nur mit diable() die aktuelle verwerfen...
     
  11. er hat nicht nach Alternativen gefragt, sondern wie man es am besten loesen kann.

    Und das mit der GUI ist schon richtig, nur ist das auch nur dort und sollte auch nur dort bleiben
     
  12. Hab die Frage nochmal genau gelesen, hast Recht.
    Habe mir gerade das Gehirn zermartert, ob ich das irgendwoanders schonmal benutzt habe. Mir fällt außer GUI nichts ein. Aber ganz ausschließen möchte ich es nicht, dass es auch woanders sinnvoll sein kann.
     
  13. hdi
    hdi
    @HimBrombeere

    Code (Java):
    void setGroesse(int groesse) {
        this.groesse = groesse;
        this.bSet = true;
    }
     
    boolean isSet() {return this.bSet;}
    void disable() {this.bSet = false;}
    Das ist nich cool. Mit solchen Methoden kann man sich schnell eklige Logik-Bugs einfangen. Ein Setter (bzw allgemeine jede Methode) sollte keine unerwarteten Seiteneffekte haben. Wenn ich setGroesse() aufrufe dann will ich dass sich die Größe ändert - nicht mehr, nicht weniger. Außerdem ist das redundant, wenn du zwei Variablen hast die eigentlich das selbe ausdrücken.

    So würd ich das in solchen Fällen dann auch lösen. Und wegen den primitiven Datentypen: Dann halt Wrapper verwenden.
     
  14. Oha, da habe ich ja was losgetreten...
    Vielen Dank erst einmal.

    Vielleicht machen wir es einfach etwas konkreter.
    Ich habe ein Programm geschrieben, in dem es möglich ist Knoten zu zeichnen, die durch Kanten verbunden werden können.
    Im konkreten Fall geht es nun darum, genau so eine Kante zu zeichnen. Die Methode
    Code (Text):
    createEdge(Point p)
    bekommt nur die Koordinaten eines Mausklicks übergeben. Mit Hilfe dieser wird dann aus einer Liste von ausgewählten Knoten der entsprechende Knoten ausgewählt.
    Da die Methode sowohl für die Wahl des Start-, als auch Endknoten benutzt wird, habe ich die anfangs geschilderte Situation.

    Die Lösung mit
    Code (Text):
    flipMyBoolean()
    finde ich sehr elegant, verständlicher wird aber sicherlich
    Code (Text):
    enableMyBoolean()
    und
    Code (Text):
    disableMyBoolean()
    sein.

    Was denkt Ihr?
     
  15. verwende statt
    Code (Text):
    enable...
    und
    Code (Text):
    disable...
    lieber
    Code (Java):
    public void setMyBoolean(boolean myBoolean) {
        this.myBoolean = myBoolean;
    }
    Dann hast du nen gewöhnlichen setter.
     
  16. hdi
    hdi
    Dann sollte das vielleicht nicht so sein. Ich denk du hast da ein kleines Design-Problem, und hast bestimmte Verantwortungen im Code an der falschen Stelle. Es lässt sich sicherlich auch ganz ohne diesen boolean lösen.
     
  17. Ok, stimmt, das ist weniger Code, der trotzdem seinen Zweck erfüllt.

    Hm..
    Bisher dachte ich eigentlich, dass es immer eine gute Idee ist, seine Methoden "so flexibel" und wiederverwendbar, wie möglich zu machen. Deshalb habe ich eine Methode geschrieben, die ich für Startknoten- und Endknotenwahl nehmen kann.
    Ist es denn besser eine Methode
    Code (Text):
    selectStartNode()
    und eine
    Code (Text):
    selectEndNode()
    , ob wohl in beiden im Prinzip derselbe Code steht? Für mich wäre das dann redundanter Code, den es zu vermeiden gilt. ???:L
     
  18. hdi
    hdi
    Ja wie, selber Code? Ist Start- und Endknoten nun das selbe für deine Logik oder nicht? Wenn nicht dann kann es ja nicht der selbe Code sein. Du hast irgendwo ein if() drin, oder? Zeig doch mal die Methode, bzw alles was man kennen muss um zu verstehen was die Logik dahinter ist.
     
  19. hdi
    hdi
    Schau dir mal das hier an:

    "The Clean Code Talks -- Inheritance, Polymorphism, & Testing" - YouTube

    Stichwort Strategy Pattern. Ohne deinen Code kann ich jetzt nicht sagen ob das Overkill ist oder nicht. Aber grundsätzlich sollte man if()-Statements mit Vorsicht genießen. Primitive Prüfungen sind nicht vermeidbar und auch total okay (zB bei mathematischen Vergleichen) aber wenn die Logik abhängt von einem Objekt-Zustand oder gar der Kombination mehrerer solcher, dann ist es oft sinnvoller sowas wie eben das Strategy Pattern anzuwenden. Wenn du mir deinen Code zeigst kann ich dir konkreteres sagen, ich hab das jetzt nur mal gepostet weil ich nicht weiß ob von deiner Seite aus noch was kommt
     
  20. Was heißt hier unerwartet? Man könte natürlich auch ein Changelistener (was in dem vorliegenden Fall KEINES WEGS übertrieben ist^^auf das Objekt drausfsetzen, das ist doch auch nix anderes. Also in irgendeiner Form musst du dem System ja sagen, dass sich was verändert hat... oder seh ich das falsch?
     
  21. hdi
    hdi
    Doch, das ist schon was anderes. Denn mit nem ChangeListener werde ich über die Änderung benachrichtigt (die Listener-Methode wird aufgerufen). Also weiß ich: Es hat sich etwas geändert, und jetzt muss ich so und so reagieren. Dahingegen wenn das einfach so im Setter verschluckt wird, dann wird keine Methode o.ä. aufgerufen. Der Code geht normal nach dem setter-Aufruf in der nächsten Zeile weiter, und ich hab nicht den blassesten Schimmer von der Änderung irgendeiner komischen Variable, die für mich mit dem Setter gar nix zu tun hat.
     
  22. OK... das ergibt Sinn... werde hinfort keine falschen Beiträge mehr schreiben :rtfm:
     
  23. hdi
    hdi
    Das sag ich mir auch jeden Tag. Wenn du das schaffst, sag mir wie man das hinkriegt ^^
     
  24. Also ich habe mir das Video nun halb angesehen, bekomme aber das Gefühl, dass wir von verschiedenen Sachen reden.
    Hier ist der Code, den du wolltest.
    Code (Java):
    private void createEdge(Point clickLocation) {

            Node selectedNode = selectNode(clickLocation);

            if (!getStartNodeSet()) {
                p.deselectSelectedEdges(); // Hebt Auswahl aller ausgewählten Kanten auf
                if (selectedNode != null) {
                    setStartNode(selectNode(clickLocation));
                    setStartNodeSet(true);
                    view.setStatusBarMessage("Kante hinzufügen - Zielknoten wählen");
                }
            } else {
                if (selectedNode != null) {
                    setEndNode(selectNode(clickLocation));
                    setStartNodeSet(false);
                    p.deselectAllElements(); //Hebt Auswahl aller Elemente in der Datenstruktur auf
                    view.setStatusBarMessage("Kante hinzufügen - Startknoten wählen");
                }
            }

            if (getStartNode() != null && getEndNode() != null) {
                Edge e = new Edge(getStartNode(), getEndNode());

                p.addEdge(e);

                deleteStartNode();
                deleteEndNode();
            }
        }

        private Node selectNode(Point location) {
            for (Node n : p.getSelectedNodes()) {
                if (n == isNodeSelected(location)) {
                    return n;
                }
            }
            return null;
        }
    Wie bereits gesagt, ermöglicht mir dieser Code, die Methode
    Code (Text):
    selectNode(Point location)
    sowohl für die Auswahl des Start-, als auch des Endknotens zu benutzen.
    Würde ich eine Methode
    Code (Text):
    selectStartNode(Point location)
    und eine Methode
    Code (Text):
    selectEndNode(Point location)
    haben, dann wäre der Code ziemlich redundant oder sehe ich das falsch?
     
  25. hdi
    hdi
    Ne, das siehst du absolut richtig.

    Ich muss sagen so ganz blick ich nicht durch. Deine createEdge-Methode tut eindeutig mehr als sie tun sollte. Wenn man ihrem Namen glauben schenkt - was der Fall sein sollte - sollte sie so aussehen:

    Code (Java):
    createEdge(Node n1, Node n2)
       Edge e = new Edge(n1, n2);
       p.addEdge(e);
    }
    Und klar, jetzt musst du den Rest vom Code irgendwo anders unterbringen. Und ja, irgendwo brauchst du sicherlich eine einfache if-Prüfung, um herauszufinden ob irgendwo eine Node als Start angewählt wurde oder nicht. Aber wenn du das anders aufziehst, muss das kein boolean sein. Ich seh jetzt nicht die gesamte Klasse usw, aber intuitiv würd ich sagen brauchst du einfach 2 Instanz-Variablen edgeStartNode und edgeEndNode, und in deinen mousePressed/mouseReleased methoden setzt du diese Nodes entweder auf ne Instanz die du erzeugst, oder halt auf null. Und wenn beide != null (bei mouseReleased oder wann auch immer so ne Kante erzeugt werden sollte), rufst du die edgeNode mit diesen beiden Nodes auf. Da brauchst du keinen gesonderten boolean mehr dafür.

    So nen krassen Unterschied gibt's da nicht, versteh mich nicht falsch. Ich würd jetzt auch nicht sagen dass das mit nem boolean irgendwie falsch oder doof oder sonst was wär. Ich find aber du solltest den Code mal etwas aufbröseln, und Methoden erstellen die das tun wonach sie klingen (nicht mehr und nicht weniger).

    Und

    Code (Java):
     private Node selectNode(Point location) {
            for (Node n : p.getSelectedNodes()) {
                if (n == isNodeSelected(location)) {
                    return n;
                }
            }
            return null;
        }
    sieht auch danach aus als könnte man da am Design optimmieren. Die Methode heißt selectNode, bekommt aber keine Node sondern nen Point. Aus irgendeiner Collection zieht sie sich Nodes, und dann gibt's noch ne Methode isNodeSelected die diesen Point bekommt. Und dann returnest du diese Node? Also sorry aber für mich klingt das wie ne Methode, die eine Node auswählen soll, aber nur dann, wenn diese Node bereits ausgewählt ist.. Also irgendwie strange.
     
    Zuletzt bearbeitet: 11. Jan. 2012
  26. Die Methode getStartNodeSet könnte auch einen passenderen Namen vertragen :)
    Ich vermute mal da sie in einem boolean-Kontext verwendet wird, dass die Methode die Information zurückliefert ob der StartKnoten gesetzt wurde, in dem Fall wäre isStartNodeSet() passender.
    So könnte sie auch ein Set von irgendwelchen Daten des Startknotens zurückliefern ;)

    Die If-Abfragen könnte man dann noch auf positive überprüfungen umstellen, indem man die Zweige von if-else vertauscht, positive Abfragen lassen sich leichter nachvollziehen als negationen.

    In der Methode selectNode sieht mir auch komisch aus, das hat hdi ja auch bereits angesprochen,
    Du Iterierst hier über alle selektierten Nodes und vergleichst sie dann per == Operator (nicht mit equals() !!!) mit einer Methode isNodeSelected(location). Vom Namen her erwarte ich von der Methode eher, dass sie prüft ob ein Knoten selektiert wird wenn an der Lokation geklickt wird, dann müsste der aufruft aber so aussehen : n.isNodeSelected(location). Die Methode macht offenbar also auch etwas ganz anderes als der Name vermuten lässt.

    In der Hauptmethode selbst reagierst du ja auch auf einen Klick, was mir hier noch auffällt ist, dass
    du einmal den selectedNode ermittelst und die lokal speicherst, aber da wo du ihn verwenden könntest (z.B. in Zeile 8) ermittelst du ihn gerade nochmal neu Anstatt dein schon berechnetes Ergebnis zu verwenden.

    Kannst du evtl noch etwas mehr Code von den anderen angesprochenen Methoden zeigen?
    Dann kann man die Abhängigkeiten der Methoden vielleicht besser auseinanderziehen.

    Gruß
     
  27. Nachdem Ihr beide meinen Code so schön auseinander gepflückt habt und die ersten Tränen getrocknet sind, bin ich zu dem Entschluss gekommen das ganze noch einmal zu überarbeiten. :D

    Möchte mich aber bei Euch beiden bedanken, das Ihr euch die Mühe gemacht habt. Ich hatte ja schon das Gefühl, dass hier etwas im Argen liegt. Es handelt sich um mein erstes Projekt und da bin ich für jeden Tipp dankbar.
     
  28. Hallo zusammen,

    ich glaube nun die Ursache für mein Strukturproblem gefunden zu haben.
    Mir will einfach keine sinnvolle Vorgehensweise für die Auswahl schon vorhandener Objekte einfallen.
    Meine Überlegung war, dass bei jedem Klick in die Zeichenfläche erst einmal geprüft werden soll, ob ein bereits vorhandenes Objekt ausgewählt wurde. Ich weiß aber nicht, wie ich den Ablauf vernünftig umsetzten soll.
    Wäre für etwas Inspiration sehr dankbar.
     
  29. hdi
    hdi
    Ich kann mir noch immer nicht genau vorstellen was man in deinem Programm eigentlich macht. Man hat ne Zeichenfläche, und kann dort Knoten erstellen und diese mit Linien miteinander verbinden? Kann man noch mehr machen? Anders gefragt: Meinst du mit "vorhandenes Objekt" nun einen Knoten, oder kann das auch was anderes sein?
     
  30. Hallo,

    Ok, dann will ich mal versuchen das zu erklären. Grob soll einem das Programm ermöglichen eine Art Schaltnetz zu zeichnen.
    Genau, man hat eine Zeichenfläche und auf dieser kann man je nachdem, welchen Menupunkt man ausgewählt hat, Knoten oder Kanten hinzufügen.
    Damit meine ich auch Kanten. Ich habe ein Interface Netzelement angelegt und Kanten und Knoten implementieren dieses.

    Mittlerweile bin ich auch ein kleines bisschen weiter gekommen. Ich habe nun eine Methode
    Code (Text):
    isNetElementClicked()
    und eine
    Code (Text):
    getClickedNetElement()
    hinzugefügt und die bereits vorhanden Methoden so umgeschrieben, dass sie tun, was sie sollen bzw. was man erwartet.
    Trotzdem würde mich interessieren, wie Du/Ihr das lösen würdest/würdet.
     
  31. hdi
    hdi
    Klingt doch okay. Solange die getClickedNetElement() oder die isNetElementClicked() jetzt jeweils aus nicht mehr als ein paar wenigen Zeilen besteht. Wenn du da jetzt wieder komplexere Logik drin hast stimmt noch immer was nicht im Design.

    Um da was allgemeineres sagen zu können müsste man wissen wie der Aufbau deines Netzes ist, sowohl logisch als auch grafisch. Du sagst du hast Knoten und Kanten. Ich finde zB dass im Core Model sowas wie ne Kante gar nicht braucht. Die einzelnen Knoten haben ne Liste mit Referenzen auf in- und out-Knoten. Dadurch definieren sich ja die Kanten, also wenn Knoten A ne Referenz auf Knoten B hat und umgekehrt, dann ist das offensichtlich ne Verbindung = Kante. Wieso also ne Klasse Kante? Wie sehen denn deine Klassen Knoten & Kante aus? Und dieses NetElement-Interface.. nutzt du das einfach als Marker Interface? (Leeres Interface ohne Methoden)
     
  32. Hier sollte nun alles in Ordnung sein.

    Ich hatte mich damals dafür entschieden, dass ich eine Klasse Kante mache, da beim Löschen eines Knoten auch alle seine ein- und ausgehenden Kanten gelöscht werden sollen.
    Es wäre sicherlich auch so gegangen, wie Du es beschrieben hast. Ob es einfacher gewesen wäre, weiß ich nicht. Aber da es sich um ein Projekt mit Abgabetermin (war bereits) handelt, möchte ich jetzt nicht noch einmal alles komplett umschreiben. Die bisherigen Änderungen sind schon weitgehender als ich dachte.
    Nach der Sichtung des Programms wird es noch eine Korrekturphase geben. Mal sehen, was beanstandet wird.

    Ja, es ist im Prinzip nur ein Marker Interface.
     
  33. Kostenlose Java-Grundlagen DVD im Wert von 29,95 € heute kostenlos sichern (Klick)
Die Seite wird geladen...

Gegenteil von Setter-Methoden - Ähnliche Themen

Forum Datum
"Gegenteil" von % Java Basics - Anfänger-Themen 20. Apr. 2012
Gegenteil einer Applet Java Basics - Anfänger-Themen 12. März 2011
String - Gegenteil von Split? Java Basics - Anfänger-Themen 7. Mai 2010
Gegenteil von Equal Java Basics - Anfänger-Themen 20. Apr. 2006
immer Setter-Methoden verwenden? Java Basics - Anfänger-Themen 8. Aug. 2010
Interessante Stellenangebote


Weitere Stellenanzeigen

Stellenanzeige Mediadaten