Hi Andrew,
you can easily create your own subclasses that use lambdas for what you
need.
Thus I don't see a reason why Wicket should support this additionally to
the well-known hook-methods.
Have fun
Sven
On 08.02.2017 11:45, Andrew Geery wrote:
Rather than using static factory methods, would we ever consider pushing
the lambdas into the component classes themselves?
For example, if we did this with the Button class, the change would be:
- Add two private fields, SerializableConsumer<Button> submitHandler,
errorHandler
- Add "setters" for these fields -- e.g., Button
submitHandler(SerializableConsumer<Button> submitHandler)
- Modify the onSubmit() and onError() methods to call the handler methods
if they are not null
A call would be something like:
add(new Button("button").submitHandler(b -> System.out.println("clicked"));
Obviously, it is still possible to sub-class Button and override
onSubmit(), so existing code will continue to work. However, for code
going forward, it should be much less needed and, in my opinion, much
clearer.
Another advantage to doing things this way is that sub-classes inherit
these methods and there is no need to add static factory methods for every
sub-class (sub-classes of AjaxButton would be a better example of this).
Thanks
Andrew
On Wed, Feb 8, 2017 at 3:42 AM, Martijn Dashorst <[email protected]
wrote:
It is that your trivial use case is not my trivial use case and that
we will end up with a 100,000 trivial use cases.
And no, confusion is not the big issue (though for onsubmit+onerror it
is) but creating a good API is hard. It takes time and understanding.
Minimizing lines of code is not the only metric for a good API.
Just as using inheritance/annotations/generics for everything is bad,
introducing factory methods everywhere will not age well.
These methods are trivial for anyone to implement and should we reach
the conclusion that we actually need the factory methods in core, it
is trivial to refactor them towards the Wicket supplied factories.
Are the factory methods in the way? Yes they are, because once we add
them, we can't evolve them without adding many more (introduce bloat)
or having to wait until a new major release.
Martijn
On Tue, Feb 7, 2017 at 11:40 PM, Martin Grigorov <[email protected]>
wrote:
Hi,
These methods are factories for the trivial use cases where nothing else
needs to be overridden but the action method (methods, when there is
onError()). They do help to reduce the verbosity!
There are plenty of those cases. You can see many usages in
wicket-examples. I have used such methods from wicketstuff-scala in one
of
my projects in the past and I use similar ones in a project with Kotlin
now.
A builder that provides methods like onConfigure(), onComponentTag(),
onDetach(), ... would look really strange!
Who will use it instead of just creating a (inner) class ?!
But if those factory methods confuse core developers then they will be
even
more confusing to normal users :-/
0 from me.
Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov
On Tue, Feb 7, 2017 at 5:07 PM, Martijn Dashorst <
[email protected]
wrote:
All,
I want to remove all component factory methods that are added for
lambda's.
My reasoning is that:
- removing them in 8.x (x > 0) is impossible
- adding them in 8.x (x > 0) is trivial
- we currently don't have a way to know what good idioms are
- having these factories push (new) developers to use the wrong idiom
- factory methods don't allow for additional overriding, thus a
combinatorial explosion of API
- I tend to think that builders are better suited as component factories
Because it is trivial to re-introduce these factories or their
replacements at a later time, I propose to remove them now and figure
out in our actual applications what works, and what doesn't. I also
think that just doing the conversion from W7 to W8 isn't enough to
figure this out.
Example 1:
Button.java has two factory methods:
Button#onSubmit(String, SerializableConsumer<Button>), and
Button#onSubmit(String, SerializableConsumer<Button>,
SerializableConsumer<Button>)
It is not possible to see without resorting to parameter naming,
hovering etc to see which functionality is bound by which parameter. I
find the naming confusing: onSubmit and onSubmit.
Example 2:
Behavior.java has two factory methods:
Behavior onTag(SerializableBiConsumer<Component, ComponentTag>)
Behavior onAttribute(String name,
SerializableFunction<String, CharSequence> onAttribute)
These achieve basically the same functionality, but other life cycle
events of Behavior don't have factory methods. NOR should they.
Example 3:
Lambdas.java has many factory methods, most of which are better
implemented by just using an anonymous inner class. For example,
Lambdas.link: often times you need to override onconfigure or
oncomponenttag as well as onclick.
Martijn
--
Become a Wicket expert, learn from the best: http://wicketinaction.com