BorderTech / wcomponents

Accessible Web UI Framework for Enterprise
GNU General Public License v3.0
21 stars 17 forks source link

Support for method chaining #49

Open Joshua-Barclay opened 9 years ago

Joshua-Barclay commented 9 years ago

Many WComponents have an extensive list of configuration options such as set title, add component, set layout etc. Configuring a component without method chaining can become quite onerous: WPanel panel = new Wpanel(Type.Chrome); panel.setTitleText("title"); panel.add(fieldLayout); panel.add(footer); panel.add(button);

The code would be simpler and more concise if method changing was introduced: WPanel panel = new WPanel(Type.Chrome).setTitleText("title").add(fieldLayout).add(footer).add(button);

Given that the majority of these configuration methods have a void return type, it should be a very low-impact change to allow method chaining.

jonathanaustin commented 9 years ago

We have always been cautious of chaining. It can make code hard to read and debug as it has many statements on the one line. This does go against the convention of one statement per line.

We can see the benefit in certain boiler plate situations. In fact we already have some "builder" patterns in WComponents (eg SubordinateBuilder).

In this case, WPanel does look like a good candidate for this pattern.

WTable is also another heavily configured component that could lend itself to this pattern.

JohnMcGuinness commented 9 years ago

A good example of the suggestion Josh has made is the WPanels class in the project I'm working on atm.

For example:

final WPanel myVAlignedPanelWithSpacingof12 = WPanels.withNewPanel().alignVertical(12).apply();

or

final WPanel myChromePanelWithTitleAndId = WPanels.with(MyPanel1).setType(Type.CHROME).setTitleText("My Panel").setIdName("id").apply();
ricksbrown commented 6 years ago

We have discussed this. While the simplest implementation would be to simply make all setters return an instance of the class in question this would be a breaking API. It would also require us to override ALL inherited which would prevent us from even making setters final which can create some issues when calling setters / modifiers from a constructor. Long story short the simple solution is fraught with side effects not worth it.

For this reason the proposed model of creating separate builder classes is the way to go.

The most efficient approach to solving this is to identify which widgets would benefit most from the builder pattern, e.g. WPanel, WTable. Possibly Inputs.

Anyone who wishes to porpose candidate components please comment on this issue or create a PR with the builder class.

A possible naming convention may be: ComponentName + Builder, e.g. WPanelBuilder. Perhaps they should all be placed in a builder package.