views:

402

answers:

4

I recently started working in Java and was introduced to the wild and crazy world of getters and setters for everything. I hated it at first, but quickly got used to it. Too used to it.

I have been spending a lot of time lately thinking more about class design. One of the things I am trying to do is avoid the trap of doing getters and setters for everything. However, much of the work I do is with entities that are mainly data containers and I am not certain that getters and setters are actually inappropriate in these cases.

Here is a simple example using public properties.

class Space {
    public String name;
    public String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
}

Here is a simple example using private properties and using getters and setters.

class Space {
    private String name;
    private String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
    public String getName() {
        return this.name;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public String getDescription() {
        return this.description;
    }
    public void setDescription(final String description) {
        this.description = description;
    }
}

In these examples, both the name and the description fields should be able to be changed.

I feel like the getter/setter example is more clear and hides the implementation details of what name and description are. It would also allow for validation on set later if needed.

I have read several discussions about getters and setters being evil and/or an anti-pattern, but it really feels like those might not apply to this situation.

Maybe there are some options I have not yet considered. I'm open for suggestions!

+3  A: 

To put it simple:

  • You need getters for all fields that must be read from the outside.
  • You need setters for all fields that must be written from the outside.

This can be 100%, but most of the time it is less.

Gamecat
I'll admit this might have been the answer I was looking for.
Beau Simensen
Jason S
+4  A: 

The first version (public properties) is not a good idea. The second is better. As Josh Bloch would say, "favor immutability":

public class Space {
    private final String name;
    private final String description;

    public Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }
}

That being said, getters and setters tend to be overused.

cletus
+1  A: 

You have heard the often oversimplified "get/setters are evil". Nobody (I hope) really means that there's anything wrong with it for data objects. I think the real idea is:

"Getters/Setters are evil, except for plain data storage objects" which itself is just an evangelism of "tell don't ask".

Ideally if a class has getters and setters, that's all it should have.

That's the argument anyway. I'm not sure I agree with it.

Draemon
A: 

While the accessor pattern helps hide the implementation details of a class (e.g. using a hashtable to store attributes to save memory on sparsely used classes), it can be very verbose to implement (your example has 12 lines more with accessors). That's why C# has a special property syntax, which allows to concisely specify default accessors:

class Space {
    public String Name { get; set; }
    public String Description { get; set; }
    Space(final String name, final String description) {
        this.Name = name;
        this.Description = description;
    }
}

Alternative forms may add access specifiers and/or code:

private String _name;
public String Name {
    get { if (_name == null) FetchName(); return _name; }
    private set { _name = value; }
}
David Schmitt