My preference is to say damn the garbage, use immutable everything and return new instances with wild abandon. My other preferences include drinking as many vodka limeaides as I feel like, but I similarly pay for that kind of overindulgence too. I also use the out parameter as last, and I often overload a version that does return a new instance, for convenience. I prefer to use fluent accessors instead of public fields.

I'm working from 10 years in software industry and my standards are very far far of yours.

- fields are always private, if you need access, a get/set is intended for. if you want to optimize (a very little), you can force the getter to be final (that can be a good contract in lot of cases). With the final, the .class may not use an invokevirtual that can increase performance. - Around the reference immutability, for me it's not a standard point but more a contract point of what you are doing. you can't set it as a global state. - For methods that instanciate objects that must cache references results, it depends of the aspect of this returned type. if the returned object is immutable itself (like String), it's a good approach. it's the hell if differents caller can modify your cached instances concurrently. Theses cases can always be handled by the "mind aware" of the developper but they are very dangerous since you are in a team and works on big projects.

What are your personal preferences? I'm still developing this, I go back and forth often because I never know what people really prefer.

Only ever use public fields for simple struct alike classes and only add getters and setters for few wiseley chosen members.Respect the privacy of your poor objects.Do not let the whole code base get dependent of implementation details.Encapsulation is very important no matter what domain you are working for. Quickly hacked prototypes do not necessarily deserve such strictness, but something with an intended long life as a game engine definitely.No standards, but some of my preferences, where the avoidance of static is a favorite of mine.

Lethal Running - a RPG about a deadly game show held in a futuristic dysoptian society.

most fields should be publicly accessible, using the getter/setter approach is often unnecessary for games (it is necessary when classes implement interfaces)

getters/setters only exist for interfaces or for developers who like using them

Reference Immutability

public fields tend to be final so the reference to that field can be passed around

if a public field is not final, it is meant to hold the reference to a field on an entity with a final field

Memory Model Nescient

methods that typically return non-primitive values have a reference to the return type as the last argument of the method

avoid calling new at all costs, use memory managers (interface with alloc/free) which the user defines (either pooling objects or not pooling objects)

[/list]

Some notes, from past experiences in my projects:

- if a class needs many public members, it's likely that your architecture is bad- make all public member variables final. Otherwise use getter/setter- Return the objects as return values. Java has not way to clearly let the programmer know about in/out/ and inout parameter. Maybe all parameter logical "in" parameters, and use returned objects instead of "out" paramaters.- New isn't always that expensive. Don't overengineer. Use pools only if you know that new() is a performance bottleneck. The GC these days is much better than many people think. I often am surprised myself if I code sloppy and it still runs well, although my code created real lots of garbage objects.- Be double careful when pooling large objects. They have a "memory preservation" side effect which sometimes hinders the garbage collector to run efficiently, but more seriously reduces the amount of available ram.

More tips:

- Split methods if the method body begins doing several tasks.- Split classes if they deal with too many concerns.- Dont't use singletons, unless you are 100% and 100% sure that it indeed is a good idea. And even if you are 100% sure, two years later it might show as a bad idea.- Avoid static containers- Avoid public static containers even more.- Use method comments for nontrivial methods. Explain what it does. Also explain expected/allowed/forbidden paramter ranges/values.- Throw "IllegalArgumentExceptions" for bad arguments, particularly if your code is used by other people, to let them know that a parameter was outside the accepted range. Don't die silent.- Delegation is more flexible than inheritance- Dependency injection is a useful pattern- Immutable objects help to avoid pitfalls- Write modules independently. Test them independently. If you notice that you can't have independent tests, your architecture most likely has a problem.- Prefer simple code about magic code, even if you are proud on your magic. (-> KISS principle)

I'm working from 10 years in software industry and my standards are very far far of yours. - fields are always private, if you need access, a get/set is intended for. if you want to optimize (a very little), you can force the getter to be final (that can be a good contract in lot of cases). With the final, the .class may not use an invokevirtual that can increase performance. - Around the reference immutability, for me it's not a standard point but more a contract point of what you are doing. you can't set it as a global state. - For methods that instanciate objects that must cache references results, it depends of the aspect of this returned type. if the returned object is immutable itself (like String), it's a good approach. it's the hell if differents caller can modify your cached instances concurrently. Theses cases can always be handled by the "mind aware" of the developper but they are very dangerous since you are in a team and works on big projects.

I would agree with you if we were talking normal/professional programming.

I would have to disagree with this, I don't like passing around a reference to an object (Game, a registry-like class, etc) when there will always be a single instance of this object. I'm dealing with this nightmare on my current project, from the get-go I should have made a few of my classes singletons... now that they aren't I'm passing around references like crazy... even into classes that don't need it only so child classes can have access to those references.

Quote

- if a class needs many public members, it's likely that your architecture is bad- make all public member variables final. Otherwise use getter/setter

It doesn't need public members, I prefer it... and yes 99% of them are final.

Quote

- Return the objects as return values. Java has not way to clearly let the programmer know about in/out/ and inout parameter. Maybe all paramater "in" paramers, and use returned objects instead of "out" paramaters.- New isn't always that expensive. Don't overengineer. Use pools only if you know that new() is a performance bottleneck. The GC these days is much better than many people think. I often am surprised myself if I code sloppy and it still runs well, although my code created real lots of garbage objects.

I name my out parameter "out" and I also always return it. If they want to use new they can themselves:

1

Vec2factual = sprite.getActualPosition(newVec2f());

Of course vectors are a bad example, since they don't take up that much space either way.

I also do this because I have my engine partly ported over to C++

Quote

- Be double careful when pooling large objects. They have a "memory preservation" side effect which sometimes hinders the garbage collector to run efficiently, but more seriously reduces the amount of available ram.

That's why I have two implementations: one pools and the other doesn't. I've experienced huge boosts in performance from pooling things like particles, and no boost when pooling most other things.

Quote

- Split methods if the method body begins doing several tasks.- Don't use singletons, unless you are 100% and 100% persent sure that it indeed is a good idea. And even if you are 100% sure, two years later it might show as a bad idea.- Avoid global containers (static ones).- Use method comments for nontrivial methods. Explain what it does. Also explain expected/allowed/forbidden paramter ranges/values.- Throw "IllegalArgumentExceptions" for bad arguments, particularly if your code is used by other people, to let them know that a parameter was outside the accepted range. Don't die silent.- Delegation is more flexible than inheritance- Dependency injection is a useful pattern- Write modules independently. Test them independently. If you notice that you can't have independent tests, your architecture most likely has a problem.- Prefer simple code about magic code, even if you are proud on your magic. (-> KISS principle)

Myself I consider them just guidelines. Depending on the project type my code ranges from very sloppy (quick dirty stuff for my own entertainment) to super-strict and clean if I'm about to write a library to be used by other people.

Eventually the key point is to know the reasons behind the rules, know why the practíses are considered good. This frees you from following them word by word, as you can understand when they make sense and when they don't.

And as it's often said, different environments (near realtime apps, business apps, entertainment/games, one-time development, development for re-use or component development) all emphasize some of the points more than the others. While I don't like the extreme argument of "this is game programming, so clean code is unneccessary", it's pretty clear that the usefulness of coding guidelines depends on how big your codebase is expected to become, how many people will work with it, and how long you've got to maintain it. And yes, games are usually finite development, so the "how long" is usually much shorter than for a business app with tens of folloup releases or a library that is in use for 20 years in hundreds of environments, also the teams are often small.

I would have to disagree with this, I don't like passing around a reference to an object (Game, a registry-like class, etc) when there will always be a single instance of this object. I'm dealing with this nightmare on my current project, from the get-go I should have made a few of my classes singletons... now that they aren't I'm passing around references like crazy... even into classes that don't need it only so child classes can have access to those references.

This was a problem I was facing also, I wanted to do things right and pass all needed references around, but then you have this reference hell as you mentioned. One the one hand I think it is right that one has to declare all dependencies in the constructor and not depend on some Globaltons, because they hide dependecy. And when you hava a constructor with 10 needed dependencies, perhaps your class design is wrong.

On the other hand it is not good that a class needs to now all dependencies for classes it wants to instantiate. So the thing to do is to use factorys which hides dependecies. I know that doing things like this can be some more work, but it is the right thing to do. Also, when using a DI framework like guice, this extra work isn't that much anymore.

I also follow a different set of rules when I write industry standard java code for work than for my game code. My work code is strictly vanilla, all private fields, getters and setters all plain to see, while my fun code has public fields on objects that are strictly structs, and fluent APIs everywhere else. It's partly just because I can get away with it being a single dev project, partly because I wish my rules were the standard, but mostly just for the variety.

Actually my genuinely fun code is scala, but my latest couple of projects have been pure java for pragmatic reasons. I'll probably wrap some scala around them eventually.

Exactly...different design requirements, different project "team" environments, different project lifetimes...all these factors (should) contribute to how something is designed.

Quote

Sry but I really don't like out parameters, because they are error prone. For example, getting the cross-product from a vector with itself.

On this front...I don't choose and support both. WRT: cross-product w/self issues and similar issues...well if you're supporting version that input & output can alias..then you should handle that case (and perhaps also have specialized version that ignores and states so). No doubt that (nominally) immutable is less work...only you and you're design(s) can determine if the extra effort is worthwhile. BUT having said that, follow the rule of only writing stuff that you need when you need it (or unquestionable will) need is a pretty good rule of thumb. It's really a damn shame that we don't have real macros and contracts so none of would be an issue.

Some days ago I gave the checker framework a go. It's a little framework you can run to do static code analysis, were the checks are plugins. I just tryed the Nullcheck plugin, which works that you annotate every method and field which is allowed to be null at some point and then checks against this assumption. So it warns you about, when you for example use a variable which can be null with a method which doesn't handle null values and so on. Overall it works quite well and I think it probably is a good thing, because you don't need any if null throw exception and so on.On the other hand it had some nasty warning on nullness and generic types, which I just couldn't "fix" so that it wouldn't warn me about them anymore.

So in general I think such tools would be great, perhaps not quite now but in the future.

Some days ago I gave the checker framework a go. It's a little framework you can run to do static code analysis, were the checks are plugins. I just tryed the Nullcheck plugin, which works that you annotate every method and field which is allowed to be null at some point and then checks against this assumption. So it warns you about, when you for example use a variable which can be null with a method which doesn't handle null values and so on. Overall it works quite well and I think it probably is a good thing, because you don't need any if null throw exception and so on.On the other hand it had some nasty warning on nullness and generic types, which I just couldn't "fix" so that it wouldn't warn me about them anymore.

So in general I think such tools would be great, perhaps not quite now but in the future.

I made something similar called Lawyer... it's a little library where you attach annotations to the beginning of methods which does non-null checks, range checks, parse checks, etc before or after the method runs. I thinks its called "Design by Contract" (hence the name Lawyer). Its a very small and unreleased library, it does it's magic by detecting he annotations and injecting byte code into your methods.

fields are always private, if you need access, a get/set is intended for.

If you have a getter and a setter that get and set the fields directly, your field *is* public; you might as well declare it public then and skip de getter/setter.If you have a getter that returns the field directly, your field is basically public and read-only. You might as well declare your field public final then and skip the getter.

Less code, less clutter, better readability, no worries if a slow VM (i.e. dalvik) will not generate sub-optimal code (i.e. optimize away the getters & setters).

In my opinion, a getter is *not* intended to give you access to a field: A getter should not return a field, but only its value (a copy of it).And a setter is not intended to give you access to a field, they're there because it's the only way in java interfaces to let you set a the value of a field (and again, then for safety you should set the field with a copy). (Obviously that copying is always done in java with non-objects and object references)

As safe as that is, it can potentially kill performance in games (especially on Android) as copying objects are likely to incur lots of garbage.

If you have a getter and a setter that get and set the fields directly, your field *is* public; you might as well declare it public then and skip de getter/setter.If you have a getter that returns the field directly, your field is basically public and read-only. You might as well declare your field public final then and skip the getter.

The field is an implementation details, the getter is the API.If you let the caller to use directly the field you can't rely on an implementation changes without to refactor all usages.

I take by example, if you want to change your implementation for a precise field that you want to set it lazy. You want only to read and instanciate it only when it is accessed.If you done a getter at the start point, you can reimplement the getter in order to get your lazy function without any impact of the usage.

My position is this - You can never have issues to encalupsate a field with getter and setter. (at least no new issue than the direct access version) - You can have various issues when letting direct access to your field (that become a API part your class)

So, with this reflexion, i create "get" for all fields if they needs to be publicly accessed outside.

As Cas says: that's what the refactoring fairy is for. Games are one-shots...you don't have forward/backward compat issues and N company user base that's going to be annoyed by breaking changes. Get it done and move on.

fields are always private, if you need access, a get/set is intended for.

If you have a getter and a setter that get and set the fields directly, your field *is* public; you might as well declare it public then and skip de getter/setter.If you have a getter that returns the field directly, your field is basically public and read-only. You might as well declare your field public final then and skip the getter.

Less code, less clutter, better readability, no worries if a slow VM (i.e. dalvik) will not generate sub-optimal code (i.e. optimize away the getters & setters).

Hmm :/. In 99% of most cases separate getter and setter methods are always better for various reasons:

1. Others using your object have a clearer understanding what they can do with it.2. Backwards compatibility.3. You can force someone using your object to use it properly.

That being said, working on my own projects I tend to take the lazy way out <.<

@65K: Depends on design goals and what is exposed to the "end-user". Take Quake-1. Well lots of folks licensed it...but they aren't some set of compatible, single runtime games and all changes must work for all. I'm sure that all of them made breaking changes from the 'trunk'...if you will. Each of the next various Id engines are derived works of the original and none of them are compatible...new stuff went it, older stuff goes away but it's a constant evolution (some versions more evolutionary than others). All of the various flavors used by all the different licensees are one-shots.

Games are a totally different design space from, say, the standard Java libraries...even when (if) we get jigsaw.

Someone wants to use some updated game engine/library/etc? Well either rewrite the parts you need for breaking changes or stick with the older version you're using, or go through the PITA of merging new bits you want.

Far too much emphasis is made on binary compatibility in software engineering these days. Come to think of it far too much emphasis is made on source compatibility too. It's trivial to refactor even a giant project to mitigate massive breakages now. It's largely the automated work of machines. Embrace change and shifting sands! Your life will get easier once you accept it.

Making refactoring easier is a good reason to focus on proper interfaces, to hide implementation details and minimize dependencies before.No one wants to break big business critical systems with costly testing, deployment and downtime phases, with distributed development, with locally customized extensions and lots of interfaces to weird external systems on purpose.While residing in a smaller software universe, commercial game development is always business critical as well.

Lethal Running - a RPG about a deadly game show held in a futuristic dysoptian society.

When it comes to my game engine I could care less about backward compatibility. Each release I'll note all public changes. If you want to use the new version you'll have to update your code! Having said that I've been working on a game engine since I was in highschool (7 years now) and my current architecture is definitely what I want and I can't imagine ever changing it. I think Java will never be able to progress to be a language better than C++ until they say screw backward compatibility and start fresh and add the features people have been requesting for years that have been left out. Many of the core programmers to the Java API have said this as well.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org