Java Coding Style – Using Same Name for Setter and Getter Methods

coding-stylejavareadability

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.

Best Answer

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.