PDA

View Full Version : Ext GWT public properties and JavaBeans



darrellmeyer
23 Apr 2008, 5:38 AM
The decision to use public properties in Ext GWT was a decision that was made after much deliberation and discussion with the community. Currently, public properties are only used for pre-render options that are used before a component is rendered. Methods can be called at any time.

Here are the issues:
1. Ext GWT needs a way to allow components to be "configured" before rendering.
2. Many components have a large number of config options.
2. Any solution should be typed. No config.set("frame", true);
3. It should be easy to identify pre-render options.

Possible solutions
1. Have a config object for each components that is passed in the component constructor:

ContentPanelConfig cfg = new ContentPanelConfig();
cfg.setFrame(true);
cfg.setCollapsible(true);
panel = new ContentPanel(cfg) 2. Use a config object that is accessed via the component:

panel = new ContentPanel();
panel.getConfig().setFrame(true);3. Support both 1 & 2.

4. Using a naming syntax with config options:

panel.setConfigFrame(true);
panel.setCFrame(true);
panel.setCCollapsible(true);5. Use public properties:

panel.frame = true;
panel.collapsible = true;I know Java developers are not used to using public properties and getters /setters and the standard way for an API. But keep in mind, Ext GWT is not a standard java application and has unique needs.

All that being said, we are open for feedback and suggestions. If you have an opinion, please let me know what you are thinking. If I had to pick an option that did not use properties I would probably prefer method 4 as it seems the most natural.

avrecko
23 Apr 2008, 6:19 AM
Thanks for the clarification but I don't get it.

ContentPanelConfig cfg = new ContentPanelConfig();
cfg.setFrame(true);
cfg.setCollapsible(true);
panel = new ContentPanel(cfg)
Shouldn't in this case ContentPanelConfig actually be in-lined in the ContentPanel? When you extend the ContentPanel you are inheriting all of the config options anyway.

Why is there a need for ContentPanelConfig in the first place? What is wrong with plain panel.setFrame(true), panel.setCollapsable(true);?

If by some reason public fields are needed, please just supply the getters and setters it will not spoil the Java Bean feeling but you will still get public fields.

ushkinaz
23 Apr 2008, 6:27 AM
I'd vote for private fields and public accessors.
Reasons:


Java developers are used to search for setters in widgets.
Public properties means that a developer should forget about his past experience and develop new style of coding. Not good at all, since it intoduces hidden cost into our projects.
Public properties: this approach means that all my code should implement same approach. Which is bad, IMO. All my automated codesmell checkers will yell at me. I'll be spammed with false alarms, which means I'll ignore them, which means I'll have high chance of missing important ones.
Related to 3) All my code reviewers are have to learn that public properties are ok. Introduces hidden cost.
Consider this scenario: MyWidget is inherited from Widget. I need to have a property, which value is calculated from Widget.width property. With setter it's easy - just override setWidth() and do your (possibly heavy) calculations there. With public fields - well, more complex and obscure approach should be implemented.
Regarding your remark to "Ext GWT is not a standard java application". I don't think that Ext GWT is THAT different. It could be compared to SWING, Tapestry, Wicket and many more. AFAIK, none of these great libraries are using public fields. And lifecycle of widgets in these libs are simular to lifecycle in Ext GWT.
Tools support. Approach 1), 2) and 3) will introduce some difficulties to tools providers, since configuration objects should be correctly recognized and editors provided. 4) is standard, there will be little need for tailoring. 5) is in question.
setters/getters might be declared in interfaces. public field can not. See GWT's interfaces like HasAlignment (http://google-web-toolkit.googlecode.com/svn/javadoc/1.4/com/google/gwt/user/client/ui/HasAlignment.html) for use cases.
1) could be nice. Nicest thing about it - I could easily share/clone configuration objects between widgets. Cool.


As an addition, refactoring existing code in Ext GWT is reeeeealy easy. Just 1 click on every class in my IDE of choice :)

ChadBourque
23 Apr 2008, 6:29 AM
Darrell,

Personally, I like option 3. Have separate configuration objects that are accessible from the widgets themselves. That has the benefit of completely separating the pre-render configuration away from the widget itself while still making easily accessible from the widget. It also allows for the creation of a single configuration object that can used for multiple widgets that you want to all have the same configuration.

Anyway, that's how I see it. Take it for what it's worth.

ushkinaz
23 Apr 2008, 6:34 AM
One thing I forgot. With public fields you can't add validations.

damsca
23 Apr 2008, 6:43 AM
Hi Darrell,

I'm happy with any of proposed syntaxes. My main concern is upward compatibility, The code shouldn't have to be changed because a property becomes dynamic.

jayj
23 Apr 2008, 8:35 AM
+1 for option 4 for the same reasons that others have pointed out above. I'd also be happy with a standard setter that throws if it does not support being used after rendering as long as the javadoc states this clearly.

Cameron Braid
23 Apr 2008, 9:35 AM
I don't mind using public fields, however this breaks encapsulation and makes it more difficult to evolve the API.

I don't like the idea of a setter prefix.

I vote for using protected (or private) fields with public mutators.

This is how I think the code should look.


/**
* <p>NOTE : pre render property</p>
* describe the property here
*/
public void setFrame(boolean frame) {
assertNotRendered();
this.frame = frame.
}
private boolean frame;

add into Component
protected void assertNotRendered() {
assert !isRendered() : "property can only be set before the component is rendered";
}

ushkinaz
23 Apr 2008, 9:46 AM
I'd vote for what Cameron said.

sheesh-kebab
23 Apr 2008, 10:31 AM
If public properties are so annoying to folks (as a java developer I see why, although as a groovy/python developer I really like them), I'd prefer either:

a) simple getters/setters, a la Swing (although I'm not too keen about that assertion code that Cameron is suggesting - too verbose)

b) config object (option 1, I think)

I don't know how intuitive option 4 would be - looks a kind of weird, but I haven't really tried it.

ushkinaz
23 Apr 2008, 10:38 AM
Cool, I've missed prefix part in option 4 )))) I don't like the prefix, public accessors are much better in my opinion.

Sorry for my misunderstanding. I've edited my first post.

Cameron Braid
23 Apr 2008, 10:52 AM
If public properties are so annoying to folks (as a java developer I see why, although as a groovy/python developer I really like them), I'd prefer either:

a) simple getters/setters, a la Swing (although I'm not too keen about that assertion code that Cameron is suggesting - too verbose)

b) config object (option 1, I think)

I don't know how intuitive option 4 would be - looks a kind of weird, but I haven't really tried it.


a) I am suggesting simple getters/setters. the assertion code will be stripped by the GWT compiler, however it it a great development tool to fail fast when you are doing the wong thing.

b) I think a config object is the wrong approach

* Using a config object sounds like a contradiction to your first statement ( simple getters/setters, a la Swing ) Swing doesn't use config objects.

* why add an extra class to hold state when the component can equaly well do this.

sheesh-kebab
23 Apr 2008, 3:01 PM
in my personal opinion either option will do (getters/setter or configs). I do agree however that getters/setters would be better/more intuitive to anyone who used Swing before (but not SWT, since SWT relies on public properties here and there).

Anyway, this topic was brought up in mygwt and talked about in great lengths.

darrellmeyer
24 Apr 2008, 8:38 AM
Ok all, looks like the public fields have been voted out. They will be removed in beta2. There will not be any config objects, the getters / setters will be added to the component itself. There will not be any naming rules. The javadocs will mark any pre-render methods and there will most likely be some asserts to test the pre-render condition. GWT will strip all the asserts when the app is compiled so there is no overhead.

ushkinaz
24 Apr 2008, 9:00 AM
Great! =)

zaccret
6 May 2008, 1:43 AM
Great and thanks for the job !
There still exists public fields in beta2 in :
- BorderLayoutData
- TreeViewer
- AppEvent
- Container

zaccret
21 May 2008, 12:54 AM
In beta3, there is only AppEvent

zaccret
9 Jun 2008, 11:22 PM
Still public fields in BaseEvent and AppEvent in beta4.