On 08/03/2011 4:07 PM, Igor Vaynberg wrote:
On Tue, Mar 8, 2011 at 11:42 AM, Maarten Billemont<lhun...@gmail.com>  wrote:
On 08 Mar 2011, at 17:54, Carl-Eric Menzel wrote:

However, there are much better arguments than existing codebase for
still allowing constructors. First, constructors are natural places to
do stuff like that. Yes, they have limitations, and yes, PostConstruct
exists for a reason, but that doesn't render constructors obsolete.
Your constructors are the perfect place to initialize your instance, at least 
at the level of your constructor's type.  Build all your instance variables 
there, handle your page parameters, and that stuff.

Just like EJBs, you should be careful about how much interaction you do beyond 
your object's scope within the constructor.  Your component doesn't have a 
hierarchy, getPage() cannot be accessed, none of your subclass constructors 
have been invoked and therefore your instance is not properly initialized and 
ready for use.
not really sure what you mean by subclass constructors or how they
come into play when constructing an instance...
If I understand correctly, here is an example of what he means :
class A extends Panel {
    public A() {
        super("anID");
        add(new Label("ALabel"));
    }

    // Hypothetic method called when a component is added
    @Override
    protected void onComponentAdd(Component component) {
        // do stuff
    }
}

class B extends A {
    private final Label label;
    public B() {
        label = new Label("BLabel");
        // etc.
    }

    @Override
    protected void onComponentAdd(Component component) {
        super.onComponentAdd(component);
        // do stuff, accessing member label => NULL pointer exception
    }
}

When an instance of B is created, the "B" part of the object is not constructed yet and B#onComponentAdd() is called anyway.

I have a c++ background and this kind of problem is even more dangerous in c++ (virtual calls don't work as normal in constructors). In Java also, I think making "this" known to the outside world before it is fully constructed is unsafe, as illustrated above.

Regarding the problem of storing Page or Panel constructor parameters:
Would it be possible to add a factory method to create Panels and Pages in Wicket like so : public static <T extends Panel> T initPanel(T instance, PageParameters parameters) {
    instance.initialize(parameters); // new method used to add() components
    instance.onInitialize();
}

This could be used like this :
setResponsePage(WicketClassSomewhere.initPanel(new MyPanel("id"), parameters);

I'm not crazy about this construct, but I'm pitching it anyway to maybe inspire someone else.

As an aside, I also just learned with this thread that I should not be adding components to a Page or Panel in the constructor but rather do it in onInitialize(). I based this design on examples, Wicket in Action and also read the 1.5 migration notes. I must have missed that somewhere!

Regards,
Bertrand Guay-Paquet

  You really shouldn't be doing anything in your constructor that is NOT 
related to initializing your constructor type's instance variables.  Touch 
anything else, invoke any methods, and you are opening pandora's box.
It's important to understand *what* constructors are a natural place for.
i think code like this should be possible:

NameEditor e=new NameEditor("name", firstNameModel, lastNameModel);
e.getFirstNameEditor().setRequired(true);
e.getLastNameEditor().setEnabled(false);

its simply the "good citizen pattern" where once you have an instance
that instance is fully constructed and is ready to use. i think this
applies to most components. i think there are much fewer components
that need a page or their environment to work, and most of them are
application-specific. wicket is all about reusability, and we should
not hinder how easy and convenient it is to create and use reusable
components.

Second, if you need to use any kind of parameters for stuff you do in
onInitialize, you *must* store them in instance variables, even if you
need them just once and could have long let them be garbage collected.
Going purely post-construct would be a very bad idea for this reason.
Sorry?  Parameters?  You mean arguments to your components' constructor?  Of 
course, but you really shouldn't ever need these in onInitialize if they're not 
state.  And yes, your component's state belongs in its instance variables.  If 
this is an issue, could you enlighten me?
taking the previous example of a name editor, with constructor we have:

class nameeditor extends panel {
   public nameeditor(...) {
      add(new textfield("first",..);
      add(new textifled("last", ...);
   }
   public textfield getfirst() { return get("first"); }
   public textfield getlast() { return get("last"); }
}

without constructing components i would have to do this:

class nameeditor extends panel {
   private boolean firstNameRequired, lastNameRequired;
   private boolean firstNameEnabled, lastNameEnabled;

   protected void oninitialize() {
      add(new textfield("first",..);
      add(new textifled("last", ...);
   }

   protected void onconfigure() {
      first.setrequired(firstNameRequired).setEnabled(firstNameEnabled);
      last.setrequired(lastNameRequired).setEnabled(lastNameEnabled);
   }

   public void setFirstNameRequired(value) { firstNameRequired=value; }
   public void setLastNameRequired(value) { lastNameRequired=value; }
   public void setFirstNameEnabled(value) { firstNameEnabled=value; }
   public void setLastNameEnabled(value) { lastNameEnabled=value; }
}

notice the verbosity, and four extra and redundant slots that this
component now takes up in memory and when serialized...

-igor


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to