On Tue, Mar 8, 2011 at 11:22 PM, Maarten Billemont <lhun...@gmail.com> wrote: >>>> >>>> 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 : > > > Exactly. If B extends A and I do something in A's constructor that goes > beyond the scope of setting up A's instance variables, then I risk a > side-effect that relies on the instance to be constructed at B's level as > well. There's nothing in the JVM that prevents this and these bugs are very > hard to see and debug. They should be avoided by good coding practices.
yep, calling overridable methods from constructors is bad - you just made the case for making page.oninitialize() final... > > On 08 Mar 2011, at 22:07, Igor Vaynberg wrote: >> >> i think code like this should be possible: >> >> NameEditor e=new NameEditor("name", firstNameModel, lastNameModel); >> e.getFirstNameEditor().setRequired(true); >> e.getLastNameEditor().setEnabled(false); > >> 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"); } >> } > > Firstly, it's my opinion that you really shouldn't be doing anything to > components directly, especially not from outside your class. As for why, see > Encapsulation and Law of Demeter. neither of the two apply because nameeditor explicitly exposes the two components as part of its contract via public getters. > But if you really wanted to use this pattern, it really wouldn't have to be > as cumbersome as you make it out to be. Also, I really don't like condoning > get(String), it's nasty and very type-unfriendly. It also breaks as soon as > you do any refactoring in your component hierarchy. yes, i traded off some refactorability for better memory footprint. imho a perfectly valid trade off when memory and space are costly. > class NameEditor extends Panel { > TextField<String> firstField; > TextField<String> lastField; > @Override protected void onInitialize() { super.onInitialize(); > add(getFirst(), getLast()); } > public textfield getFirst() { if (firstField == null) firstField = new > TextField<String>(); return firstField; } > public textfield getLast() { if (lastField == null) lastField = new > TextField<String>(); return lastField; } > } there are still problems with this: *you still have the two extra memory slots that are a complete waste here - component references *the lazy init code is cumbersome to write *you are missing the two slots needed to pass models from constructor to the two textfields - so thats four extra slots total that you have now forced on users * the components i get from the getters are not added to their parent - for more complex components that need access to their markup this is a problem, eg if ("text".equals(getFirst().getMarkupTag().get("type")).......not necessarily a good example taking this particular custom component as context, but a valid usecase in plenty of other situations. -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