Making fields public that use both setters and getters

What do you all think about making fields public that have simple setters/getters? Part of my problem is that since I started using State classes, they have to access the basic Mob fields (x, y, xa, ya, etc) through setters and getters since they are not the same class and don’t reside in the same package. When field access is heavy, the setters/getters (setters more than getters, really) make the code hard to read.

So is there really any harm in making Mob fields public, since setters/getters make them essentially public in practice anyways?

Here is an example:

Player extends Mob

PlayerNormalState extends State

Player contains a State field, which currently points to an instance of PlayerNormalState

PlayerNormalState::update() updates the fields x, xa, etc. that are defined in Mob, but needs to use setters/getters since those fields are protected, making the code much harder to read and write.

Should I just make those fields public?

Keep in mind, I’m talking about setters & getters that simply assign and return values; not specialized ones that do extra computations like range checking and such.

Yes, because it introduces a bad way of thinking about designing code. Once you start with it, you will do it eventually all over your code base and end up in mess.

Just my two cents:
I don’t use getters and setters unless I have a good reason to use them.
Using simple getters and setters rather than declaring the variable public is doing the exact same thing only with a lot more boiler plate code.
If you are really bothered by the getters and setters, you could consider using lombok.

The boilerplate doesn’t bother me. It’s having to use getters and setters excessively, mostly for coordinate fields like x, y, xa, ya, etc, that bothers me.

m.x += m.xa;

looks a lot better than

m.setx(m.getx() + m.getxa());

The more complex the expression, the worse it gets. Normally that kind of code is internal to the class and therefore getter/setters don’t need to be used, but when you use State classes for your Mobs they become necessary.

I checked out Project Lombok and I don’t think it solves the problem of having to use getters/setters.

Create a function that takes in the value you want to add to your ‘x’ variable. Something like:


public void addX(int xa) {
    x += xa;
}

You can also have a ‘setX’ function that literally sets the value of ‘x’, no adding involved.

Keep your code simple, you’re asking for bugs if you use your ‘setx’ function like you did in your last post. Reuse code when you can, and make sure you reduce the number of “working parts” as much as possible. Code is going to be “ugly”, you just have to accept that. Unfortunately Java does not provide a lot of syntactic sugar to reduce some of this ugliness. But you still should follow OOP guidelines so you do not fall down a rabbit hole of bugs. Directly modifying variables without the use of basic/advanced setters is sure to bring about some issues later down the line that will be annoying to fix.

We’ve been handed a ton of improvements to the language and we are still discussing when to use getters and setters for oop programming rather than how best to set variables up for functional programming?

This is a common enough situation (objects that moves around the screen having a “position” state), that it would be really helpful to have an article that specifically explores how this might be handled via “functional programming” and the associated pros and cons.

It could be that having an object that is simply a collection of states would be helpful. I’ve seen examples of classes without any code at all, just the variables. I use this construction in the audio I do (for envelopes and for the sine-based “operators” of the phase-modulation synth), and they are working out well.

I’ve also seen examples (in functional programming) where the variables are all public and final, and the sole method is one that returns a new copy to replace the old. (Too costly when the position is changed every frame?)

Setting things up so that Streams, say, could be used for setting new locations or doing collision checking would be useful, as this automatically brings multi-core benefits without having to code synchronization or fork/joins.

So, yeah, the question is interesting but I wish it were asked in reference to good fp practices rather than oop.

[EDIT: all the searches I’ve done so far only show a couple articles on FP for Java game programming and they are behind paywalls.]

Go ahead and use public fields. There is no point in using setters and getters in your case. In OOP setters and getters can be considered an anti pattern as it breaks encapsulation. Instead of setters and getters dealing with state one should instead have methods that does stuff. But if you cant hide the state, like in your case, then you might as well just make it public.

In my project I simply use all public and make meaningful methods when I need it.

At work we have tried also Project Lombok, maybe can help you, more info here

Just imagine how much easier this would have all been if you could declare member variables in interfaces…

Cas :slight_smile:

Thanks Opiop, such a simple solution that I overlooked it. Thanks also to DopplerFrog for suggesting the same thing, although he deleted the comment for some reason. ??? This is a very helpful community.

That is a very interesting concept, philfrei. I will probably create a new branch, test that out, and see how it works. If you’re up for it and have the time, you should write an article about that!

I’d be interested in seeing what you come up with, if you post your test!

I’ve started rewriting Hexara (was Java2D/AWT/Swing) with JavaFX 8. I’ll be trying out some ideas in that process, too.

Even if the results are not conclusive pro or con, having something to chew on and discuss could lead us to come up with some good patterns, or to feel better about continuing to use the tried-and-true.

For me its pretty simple.

Rule #1: Never use public fields for objects.
Someone can make your object null and ruin your life. Also, if you aren’t using your object in a setter or do not expect a null, check for a null pointer.

Rule #2: Only make if simple types (int, char, etc.) public if you do not need controlled access or you want to listen to changes.
Controlled access means that you want to restrict the range of values. For example, if you were to represent the day of month with an int, you want to make sure that its always between 1 and 31.

The best example of good public fields is a Vector class. Components of a vector can be any number and so its A-OK to make them public.

Listening means that you want to know when changes occur and notify listeners. You cannot do if its possible to change the value arbitrarily.