0

Say I have class with a boolean member variable fancy:

public class MyClass {
    private boolean fancy;
}

Case 1. I could the define the setter and getter as follows:

// getter
public boolean isFancy() {
    return this.fancy;
}

// setter
public void setFancy(boolean fancy) {
    this.fancy = fancy;
}

Case 2. Alternatively, I could also define my setter and getter as follows:

// getter
public boolean isFancy() {
    return this.fancy;
}

// setter
public MyClass isFancy(boolean fancy) {
    this.fancy = fancy;
    return this;
}

One advantage I like is, that I can use the fluent interface to set fancy when I new my class and, I get the visual feedback of adding that attribute to my object:

MyClass mc = new MyClass().isFancy(true);

Question
My question is, is there something inherently wrong, in terms of readability, maintenance, it's just plain confusing, bad style, etc., with defining my setter and getter like in Case 2? Alternatives are welcomed.

  • 1
    Personally, I prefer your second approach. The problem is that most Java developers will not be familiar with this style; the setter is especially confusing. Java is unfortunate in this regard; first-class properties (like the ones C# has) are more intuitive, because they omit the method parentheses. – Robert Harvey Jun 25 '18 at 16:44
  • using setFancy vs isFancy does not stop you from returning this and then doing MyClass myClass = new MyClass().setFancy(true); in a fluent way. Sure the naming would feel a bit odd, so if you are going Fluent then maybe isFancy is better. But if going Fluent then I would rather have a fluent Builder with an immutable object. – Hangman4358 Jun 25 '18 at 16:52
  • @Hangman4358 I agree with you that set<prop> for a boolean feels a bit odd. I also considered using the builder approach but when the class is relatively small, having a builder seems a bit too much. Great suggestion though thanks! – StaticBeagle Jun 25 '18 at 17:09
  • 1
    Option 1 is standard setters and getters, Option 2 is a fluent API. If your fluent API had isFancy() and isNotFancy() to set or clear the fancy flag that would also work. – Berin Loritsch Jun 25 '18 at 17:27
  • 1
    I do not like case 1 because it is asymmetrical. If you have a setFancy, my nerdy mind wants to see a getFancy as its counter part. – Martin Maat Jun 25 '18 at 17:34
1

Using isFancy for a setter is certainly not a standard convention and may therefore confuse the code's readers. However, the idea of using a fluent interface is a good one. If I had to choose a name for use in your second example, I would simply use fancy(). This is a name which you can use for both the setter and getter without confusing anyone, and it is shorter than the names with set/get prefixes. Note, however, that some IDEs and other tools may not work as well if your getter/setter do not have the prefixes in their names.

Yet another thing which I like to do is making my data objects immutable. Some languages (e.g. Kotlin and Scala) make using immutable data classes even easier, but this style of programming works with Java as well. It makes functional programming easier and allows you to avoid some kinds of errors, especially in parallel code. You can combine immutability with your second approach by using a separate builder class. This adds some lines of code, but (assuming there is more than just one field), the overhead is not that bad and later the resulting object is quite pleasant to use:

public final class MyClass {
    private final boolean fancy;

    private MyClass(boolean fancy) {
        this.fancy = fancy;
    }

    public static Builder builder() {
        return new Builder();
    }

    public boolean fancy() { return fancy; }

    public static class Builder {
        private boolean fancy = false;

        public fancy(boolean fancy) { this.fancy = fancy; }

        public MyClass build() { return new MyClass(fancy); }
    }
}

An added advantage is that you can set reasonable defaults in your builder. You can also pass the builder around between methods as long as the object is being constructed, so for example fancy value can be set in several different places if that's needed, but once you create the final object via build(), it is immutable and thus threadsafe (and you know that at this point it can't be modified in any unintended way).

So the short way of building your object is:

builder().fancy(true).build();

but you can also split it into multiple calls:

Builder builder = builder();
builder.fancy(result_of_some_calculation)
// do other stuff
if (something) {
    builder.fancy(result_of_another_calculation)
}
callSomeMethod(builder.build())

Of course, the more fields you have, the more use you will gain from using the builder pattern with immutable data class.

0

I wouldn’t say anything is inherently wrong with it. But it’s not the kind of method name I would be looking for if I was looking for a setter. With that name I might expect to be able to retrieve whether the object is fancy, with some kind of boolean switch (which I would not suggest either, but that’s off-topic)

I suppose it depends on who else is reading the code and if you really want to get in this habit. If you’re always writing code for yourself then you can certainly go with what feels good for you.

(You could always write Scala where none of this matters, or any other language on top of the JVM with native get/setters or some other mechanism)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.