Use of protected assetManager variable in tutorials

The beginner tutorials refer to the protected assetManager variable which is undocumented. Surely getters and setters should be used instead to encourage best practise i.e. the supplied getAssetManager and setAssetManager



The reason why I bring this up is because I encountered a strange problem in scala.

The following code executes fine:

[java]

MyApplication extends SimpleApplication

{

override def simpleInitApp =

{



new Material(

assetManager,

"Common/MatDefs/Misc/Unshaded.j3md")

}

}

[/java]



While the following code throws a java.lang.IllegalAccessError exception:

[java]

MyApplication extends SimpleApplication

{

override def simpleInitApp =

{



for( x <- 1 to 2)

{

new Material(

assetManager,

"Common/MatDefs/Misc/Unshaded.j3md")

}

}

}

[/java]



This is because of how scala handles protected variables. But this is solved by using the getter and setter functions instead.

Well, using the variable is fine, thats why its protected and not private. Sorry to hear that scala has issues with that but its really not necessary to use the getter here.

And you can easily add getters in your own base class that extends SimpleApplication… so I’m not sure I see what the problem is.

getAssetManager() exists already in Application, and therefore in SimpleApplication and all subclasses too.



I think the point he is trying to make is that since assetManager is a protected field, and therefore does not feature in the documentation, it would be better if the tutorials encouraged the use of the getter from the off, instead of directly using the variable of the parent class. Else what is the point of having public getter/setters?

The public getters and setters are for accessing AssetManager from outside of the subclass… like from all of the app states, etc.

Well, it’s a style thing really. OO “best practices” says that member variables should be accessed via a getter(), and so that is the behaviour most programmers will expect.



Seeing a protected member variable being accessed directly certainly surprised me the first time I saw it - although I can’t say I found it confusing or unclear - just a bit odd.

Well best practice would certainbly to access the getter. But whatever,

@zarch said:
Well, it's a style thing really. OO "best practices" says that member variables should be accessed via a getter(), and so that is the behaviour most programmers will expect.

Seeing a protected member variable being accessed directly certainly surprised me the first time I saw it - although I can't say I found it confusing or unclear - just a bit odd.


On the other hand, what are protected fields for otherwise?

I admit I generally have only private fields and completely shun protected fields in general... but they have their place and they are easier and faster to use (not that speed matters at all in this case).

It is odd that they are not included in the javadoc though. It's annoying to have to open the source code every time I want to remember the protected fields of a JME class. Have them and document them, or don't and don't.

I guess the way it is right now is similar to the jME1/jME2 “paradigm” where you had a “SimpleXYZ” class and by extending it you get a bunch of protected fields. I sort of tried to keep it the same way in jME3.



Ideally you wouldn’t extend SimpleApplication at all but would create an instance of App and then add various AppStates to it, where those AppStates have the functionality of SimpleApplication.

@Momoko_Fan said:
I guess the way it is right now is similar to the jME1/jME2 "paradigm" where you had a "SimpleXYZ" class and by extending it you get a bunch of protected fields. I sort of tried to keep it the same way in jME3.

Ideally you wouldn't extend SimpleApplication at all but would create an instance of App and then add various AppStates to it, where those AppStates have the functionality of SimpleApplication.


You can do that with SimpleApplication now... you can't do it with Application because it doesn't call the state manager.

Edit: note that there are a few semi-critical things that aren't communicated to app states at the moment so you'd still have to extend simple application to override handleError(), catch the show/hide stuff, etc..

I really don’t think having protected fields is a bad practice.

I sometimes consider having public fields when i know a they have to be accessed from the outside of a class…

I always found accessors to be just a bloat, most of the time they are useless, because they have no additional code. (a private field and public accessors that only allow to read/write the attribute…what’s the point?).

I use them because of this so called “Best practice” convention, and because I learned to make things like that…but using this pattern also for protected fields is getting dumb IMO.

It’s about abstraction. By having the access through the getter/setter it means that if you change the behaviour of the class then you can do it inside the class without changing anything that uses it.



For example if you have a class containing just a simple integer you might be thinking “why do I need a getter/setter for a simple integer”…But then later on you add that object into a GUI and you want to notify the rendering section whenever it changes. If you have a setter then it’s a 30 second job. Otherwise you have to go find every reference to that variable. In more complicated examples that “getX” might change from being an integer and become a call to another method, or involve some math, or whatever.



It’s the same reason that unless you need specific functionality of an implementation you use the interface for variable types not the implementation (i.e. List instead of ArrayList). You are keeping the implementation details internal to the class and only exposing what you need to expose to the outside world.



In the example of SimpleApplication by exposing those variables as protected that means they have become part of the interface of that class with the outside world. It’s now a breaking change to the API to modify those variables.

Oh, and of course another important reason - with getters and setters you can not provide a setter. If you make the field protected then people can modify it…and then you get someone complaining that X has stopped working and you discover that it’s because some time previously they modified the internal workings of your class.



In simple application could/would/should someone extending it change the asset manager without breaking things? If the answer is no then why would you provide them the ability to break things when there is no valid thing they could be doing with that functionality anyway?

I never use private, unless its a method that needs to be accessed from within the constructor. And that’s just to avoid the warning you in netbeans (until I disable it, like all the others). Private makes it impossible to override classes, because you don’t get full access to the the superclass functionality. You become a guest in your own home.



People citing the “intended use” of classes and member variables as an argument for this are morons who can’t think outside the box, so they try and force others not to do it as well. I think most of them are probably wearing helmets when they’re programming; making quick stabs at the keyboard when they type, whimpering, then quickly retracting their fingers and hand. Yes we know in theory this is right, and when you make that textbook 20 line bank balance stuff it’s appropritate, but not otherwise. Grow up. Stop using private. If you don’t want a class overriden, or intend to make it impossible to work with, at least make it final (or use this flag in the javadoc: @garbage).



And btw. what is package private? That’s even more stupid. Who bases their actual code logic on which package a class is located in?

Whatever we decide, we should document it in any case. Either assetManager is a part of the interface or it is not, both is fine for me, however once decided it should be documented.

Using private is good to a) remove killswitches for the user and b) Unbloat the subclasses. Using a setter for the assetManager would seem dangerous to me as it should be managed by the application solely. If there was a setter any AppState could mess with your assetmanager.

And yes, we try to make you not think “out of the box” as the engine gives a pretty small and defined interface that you should use as intended. We’ve seen too many “out of the box” code lines for jME ;). Due to the simplicity of the classes you can add complexity at other levels. This I would do with my own software as well, its not about taking any possibilities from you, its about taking away the multitude of possibilities to break your game.

@androlo said:
I never use private, unless its a method that needs to be accessed from within the constructor. And that's just to avoid the warning you in netbeans (until I disable it, like all the others). Private makes it impossible to override classes, because you don't get full access to the the superclass functionality. You become a guest in your own home.

People citing the "intended use" of classes and member variables as an argument for this are morons who can't think outside the box, so they try and force others not to do it as well. I think most of them are probably wearing helmets when they're programming; making quick stabs at the keyboard when they type, whimpering, then quickly retracting their fingers and hand. Yes we know in theory this is right, and when you make that textbook 20 line bank balance stuff it's appropritate, but not otherwise. Grow up. Stop using private. If you don't want a class overriden, or intend to make it impossible to work with, at least make it final (or use this flag in the javadoc: @garbage).

And btw. what is package private? That's even more stupid. Who bases their actual code logic on which package a class is located in?


No offence but you're thinking like a small application developer not a library developer and/or large project developer.

When writing something for other people to use controlling how and when they access it becomes very important. They really are a guest in your house, so you'd rather they didn't go to the toilet in your kitchen sink ;)

Every time someone missuses a public variable and you end up having to support them and sort out the resulting mess (especially in a commercial context where they are paying you so you need to support it) you will be cursing that you let them do that in the first place.

It's not just about other people too. If you write something and then come back to it 6 months, or 6 years, later then having stuff private immediately shows you what you were and were not supposed to interact with from outside the class.

Package Private is the Java equivalent of friend classes from C++. It allows you to design a group of classes and give them more access to each other than they give to the outside world.

For example if two classes work as a pair and need to keep a value synchronized. You provide public setters that set the local value and then package private ones that are used to do the synch. That prevents anyone accidentally calling the wrong setter and the synchronization being broken. Classes inside the same package are taken to know enough about each other to safely access the package private stuff.

As soon as more than one person is using this stuff then it becomes very important, even without that it can be helpful.
@normen said:
Using a setter for the assetManager would seem dangerous to me as it should be managed by the application solely. If there was a setter any AppState could mess with your assetmanager.

I agree, which is the same problem with exposing the assetManager variable - although at least then the problem is confined to the simple application itself. Really in "correct" OO design the assetManager variable would be private and (probably) final and have a getter but no setter.

@normen said:
And yes, we try to make you not think "out of the box" as the engine gives a pretty small and defined interface that you should use as intended. We've seen too many "out of the box" code lines for jME ;). Due to the simplicity of the classes you can add complexity at other levels. This I would do with my own software as well, its not about taking any possibilities from you, its about taking away the multitude of possibilities to break your game.


Absolutely. Thinking outside the box is good (and I have once or twice come across overly restricted classes and been frustrated by it - in fact I even posted a patch to Nifty as I needed access to something that was blocked) but too many people when they think outside the box end up proving that black is white and getting killed at the next zebra crossing. To continue mixing metaphores you can give people the tools to think outside the box without inviting them to throw sand into the middle of the engine.
@zarch said:
To continue mixing metaphores you can give people the tools to think outside the box without inviting them to throw sand into the middle of the engine.

Thats exactly the intention. Ideally you just don't come up with the idea to change anything in jME because its just so slick and fits itself to any given situation if handled as intended. Like you would not come up with the idea to change core java classes and if you do you do it with those that have protected fields and not with those that you have to wrap in your own object, which would not be "changing" anymore but rather using :). If you feel like you have to change the engine all the time (which really in no case you should) then its probably the best to use vanilla OpenGL anyway. The AssetManager instance in the application is managed by the application and since its extensible that variable is obviously protected. "Best practices" back and forth, I think this is one of the most common java patterns seen.

Sorry guys I’m just saying what I found out. It’s on good authority.