Gegenteil von Setter-Methoden

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

  1. propra

    propra Neues Mitglied

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

    Sym Guest

    Code (Java):
    public void setSomethingToSet(boolean bool) {
            somethingToSet = bool;
        }
    Das is lässt man in der Regel weg. :)
     
  3. SlaterB

    SlaterB Guest

    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 ;)
     
  4. Gast2

    Gast2 Guest

    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.
     
  5. nillehammer

    nillehammer Guest

    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;
      }

    }
     
     
  6. bygones

    bygones Guest

    @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]
     
  7. Gast2

    Gast2 Guest

    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.
     
  8. nillehammer

    nillehammer Guest

    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.
     
  9. HimBromBeere

    HimBromBeere Neues Mitglied

    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...
     
  10. bygones

    bygones Guest

    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
     
  11. nillehammer

    nillehammer Guest

    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.
     
  12. hdi

    hdi Neues Mitglied

    @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.
     
  13. propra

    propra Neues Mitglied

    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?
     
  14. Gast2

    Gast2 Guest

    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.
     
  15. hdi

    hdi Neues Mitglied

    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.
     
  16. propra

    propra Neues Mitglied

    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
     
  17. hdi

    hdi Neues Mitglied

    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.
     
  18. hdi

    hdi Neues Mitglied

    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
     
  19. HimBromBeere

    HimBromBeere Neues Mitglied

    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?
     
  20. hdi

    hdi Neues Mitglied

    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.
     
Die Seite wird geladen...