PreferencesGameSettings

Does anybody have a problem with making the preferences member of PreferencesGameSettings protected instead of private?

Looking to extend it?



I don't necessarily have a problem with it, but off the top of my head can't imagine any good reason why you would need to have it protected?

Yes, I want to extend.



It's just better to have direct access to it instead of always using the getInt()/setInt() etc. Implementation wise there's really no need since all the assessors are available. It's a convenience issue.

The only problem with that is you lose the abstraction that GameSettings provides then.  What if you wanted to swap out later with a PropertiesGameSettings or DatabaseGameSettings, you wouldn't be able to do a clean swap since you've got dependencies that rely on the internals of PreferencesGameSettings.  That's the primary reason I would suggest against it.

Rawr…need less direct access and more setters+getters!  Just as darkfrog said…when working with a system whose internals can/will constantly change, it's good to be able to leave the interfaces to your classes the same…that way you don't have to change a thing, but get better performance/quality/beer!

That'd be my opinion, too. Usually you don't need any public or protected fields. Having private fields means proper encapsulation and thus allowing proper subclassing and a clean, evolving API. So:



If it's only convenience then use the setter! It's not a performance issue as it's inlined by the vm after some calls.

I couldn’t disagree more.



Proper design is not just about encapsulation, that’s just one part of it. Proper design is just as much, if not more, about extention and inheritance. Just look at the basic Java libraries. If you look at the largest inheritance trees, you’ll see protected members all the way up through the chain.



In my way of thinking there better be a very good reason to call anything private, not the other way around.



Although in this particular case it’s pretty easy to get around the private member via getters/setters, that doesn’t mean it’s correct.



Getters and setters are for users (aggregations) of instances of classes, not for implementations/extentions (is a) of the functionality.



I do find this particularly odd within this class because the Preferences instances is actually passed into the constructor. Then it’s assigned to a private member. Thus the aggregator of the PreferencesGameSettings actually and change the underlying Preferences whenever it likes. In actuallity, a particular implementation/extention of PreferencesGameSettings should be the place that knows about the location of the Preferences and excapsulate that with a default constructor.



public class MyPreferences extends PreferencesGameSettings {

I can see how you might draw such conclusions, but take a step back here.



The first question you need to ask is, "What do I gain by extending?".  Based on what you've already said you gain convenience.



The second question is, "What do I lose by extending?".  By extending an implementation of GameSettings rather than using GameSettings abstractly you lose all abstraction and modularity of the GameSettings concept.  You might as well go back to the PropertiesIO class in SimpleGame as the primary purpose of GameSettings is to modularize the implementations of settings.



To respond to your statement that everything in Java is protected.  That's not exactly accurate.  I would liken GameSettings to ArrayList.  It is an implementation of java.util.List but never meant to be extended.  The variables within the source code are all private because it is an implementation.  The same holds true for GameSettings.  However, there are various circumstances under which Java does make their variables protected for the purpose of being extended.  However, that is a design decision based on what type of object they are developing.  An implementation that should not be extended should not have protected variables.

darkfrog said:

I can see how you might draw such conclusions, but take a step back here.

The first question you need to ask is, "What do I gain by extending?".

Is the extending class your planning going to be part of jME or specific to your own game?  Do you have any possibility you might EVER want to move to another implementation of GameSettings (ex. DatabaseGameSettings) or are you definitively going to be using Preferences?

Now you have a good point there! Ideally, yes, there may be a desire to some time in the future allow for non-preferences based GameSettings.



So your point is well made. If I was using getters/setters only then the only change I'd have to make to use a different GameSettings implementation would be the constructor.



Deal. I can't argue with that.



I would then not extend PreferencesGameSettings, but rather aggregate it. Wouldn't it make more sense then to just pass in the root node Sting to the PreferencesGameSettings constructor instead of the Preferences instance; since the same string to DatabaseGameSettings would mean something different, depending on implementation, but would be encapsulated?

However,



Now that I think about it that defeats what the Preferences class is all about.



Rather wouldn’t I add in a DatabasePreferencesFactory via

System.setProperty(“java.util.prefs.PreferencesFactory”, <class>)

and use that to create my Preferences that would be passed into PreferencesGameSettings constructor?



Then extending PreferencesGameSettings would be the more correct thing to do! Aaah! Now my head is spinning.

hehe…well, that is presupposing that we would want to continue using Preferences in the future.  I'm a big fan of Preferences (sort of why I wrote PreferencesGameSettings), but since the standard before I came onto the scene was PropertiesIO and my expectation was that people might want to continue using that, use the preferences system, or perhaps move to something else entirely I decided to abstract GameSettings to allow any implementation necessary.  We may want to modify PreferencesGameSettings to be able to support more than it does, but I don't believe Preferences will necessarily give us everything we might ever want.



One good example I can think of is a game that maintains user settings on the server.  When the getter is called it actually does a call to the server to request that information (that might be necessary depending on how much information is stored for that user).  Perhaps that's a corner-case, but I didn't want to exclude the possibility.  My goal was to introduce GameSettings in StandardGame and eventually convince other devs to make it a global replacement of PropertiesIO.