OOD inadequacies

Most of the central classes of jME require one to branch the code just for

basic modifications.  IMO, this conflicts with the stated goals and touted

advantages of jME.  Basically, any class that I want to modify, I have to

duplicate huge chunks of original code or (what is more practical in this

situation-- replace the jME class with my own copy), since it is impossible for

subclasses to modify behavior.  This applies to the jME games, game states,

JMEDesktop.



If a class is made to facilitate subclassing, then (1) if it's likely that a member

needs to be even just read by a subclass, then it should be protected not

private, or at least provide getters and setters for critical components; and

(2) there should be at least one constructor provided that does not apply all

"settings".  To clarify the second point, I'll give an example.



Darkfrog and others on the development team seem to prefer not subclassing

StandardGame, but StandardGame is designed so that you can do very little

without not only subclassing, but without either duplicating much of the

original class or replacing it entirely.  Here is the most trivial

customization I can think of:  I want my code to specify whether to display the

game settings dialog, (for example if a user gives a command-line switch to my

game, or if they click a button on the login screen).  It is impossible to do

this without replacing (not just subclassing) the StandardGame class.  The

work-around I have used so far is to zero the Java Preferences object, but that

is a bad work-around, since the user usually wants to adjust existing settings,

not start from scratch.  StandardGame will run the settings dialog if there are no

settings and will not otherwise.



You can't adjust this behavior because there is no opportunity to modify any

instance behavior since everything is done inside the constructor.  If you

subclass, you still have to super to one of the provided StandardGame

constructors.  A year or so ago I did a minor refactor to the games to make

proper use of the GameSettings interface, and you can see my comment from

when I did that work in StandardGame.java:  you have to subclass to modify

settings dialog behavior… but what I didn't mention at the time (my target

at the time was not with subclassing), was that you have to duplicate half of

the class in order to subclass.



I think jME would benefit greatly if the central classes would use the

following idiom:



 public initialized = false;
    // "initialized" signifies that instance is constructed and ready for use.
    protected int width;
    // "width" starts at 0 here, so must be set somehow before instance is initialized
    protected ConfigShowMode configShowMode = DEFAULT_CONFIG_SHOW_MODE;

    /** Convenience constructor */
    publid AClass(int width, int height) {
        setWidth(width);
        ..

    /** JavaBean constructor */
    public AClass() {
    }

    protected void oneOfMultipleSetupMethods() {
    // A method to set up the screen, for example.
    // It is protected so that subclasses may override and super() it,
    // or make their own constructor that invokes it.
        if (...  Verify that required properties have been set before using

    protected init() {
        if (width < 1 ||...) {  // Validate that critical settings have been made
            throw new IllegalStateExceptin(
            "A required property has not been set.  One of..."0;
        // Do all the work that is currently in the base jME constructors
        ...
        oneOfMultipleSetupMethods();
        twoOf...
        initialized = true;
    }

    public void setWidth(int width) {...
    // Allow user the opportunity to modify the instance assembly before it
    // is too late.  Use setters for everything that can be modified.

    public void setConfigShowMode(...

    public void businessMethod() {
        if (!initialized) {
            throw IllegalStateException("Instance not initialized");



This is worlds better in both respects:


  • Users can modify the behavior using the setters, without subclassing at all.


  • When a user needs to subclass, they get optimal code re-use since the meat
    of the code is "protected".


There is no need to subclass StandardGame to replace GameSettings since before you create StandardGame you can prompt for settings yourself and then pass those GameSettings into StandardGame.



StandardGame is meant to be used, not extended.  If you need something that StandardGame doesn't provide you have all of the AbstractGame, BaseGame, etc. that were built upon to create StandardGame that you can write your own.  Ideally StandardGame will work for all "standard" scenarios, but if it doesn't then suggest a patch that will allow it to do so without subclassing.  StandardGame is one of the very few aspects in jME that doesn't explicitly require subclassing to work.  I did this with the belief that it simplifies development and I know many many people are using it without the need to subclass.

I must sound very pessimistic in this topic.  I’d like to say that I very much appreciate all of the jME classes under discussion, and if I must branch classes sometimes, that is still much, much easier than working with Java3D, which is what I worked with previously.  I benefit greatly from Darkfrog’s work in particular, and it is really surprising how often I look for a way to accommodate some use case just to find that it has already been anticipated and supported.  I am a fan.



The goal of this topic was to hopefully reduce the difficulty of user-customization of the basic jME classes.  I only used StandardGame as an example because the show-config behavior provided a simple yet opaque case of the difficulty I am talking about. 

Well, a lot of changes have been made to what I came up with originally in StandardGame, so it would seem some things have gone off in a direction I did not intend.  You see, I originally wrote StandardGame to ignore the old settings system, but then my new GameSettings concept got put backwards into the code.  The way I designed StandardGame in the first place was to not use the AbstractGame feature to display game settings, I wrote my own GameSettingsPanel that you could choose to use or not to edit GameSettings before the game was started or while the game was going (but it had nothing to do with StandardGame). I prefer my original idea of removing this as something that is built into the game itself and rather make it something the developer chooses to do outside thus removing complexity from Game and giving more control to the developer.



I think the problem you have when you look at the code is a difference of perspective in how you want to write the code, not a difference in actually having the ability to accomplish the task.