vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
616 stars 167 forks source link

When using mixin interfaces in my components, I want to have fluent setters, so my code looks cleaner and easier to use. #1799

Open gilberto-torrezan opened 7 years ago

gilberto-torrezan commented 7 years ago

Currently the Mixin interfaces in the framework, like HasText and HasStyle have setters that are not fluent. That makes it difficult to create fully fluent components that uses those mixins.

Legioth commented 7 years ago

The problem with this is that a fluid setter in e.g. HasStyle would return HasStyle instead of e.g. Input. This means that I could do myInput.setValue("foo").setClassName("bar"), but not myInput.setClassName("foo").setValue("bar"). This has the potential of being extremely confusing for users.

HermanBovens commented 7 years ago

I would think that even if HasStyle.setClassName() returns HasStyle, Input could override the method and cast to Input (and return Input).

Legioth commented 7 years ago

Overriding all inherited fluent methods to define a more specific return type is feasible when the code is generated, but it's quite impractical in cases implemented by hand.

djarnis73 commented 3 years ago

I'm really new to Vaadin, but I really miss fluent setters as well, especially when building UI with the various Layout classes (I miss being able to do add(new HorizontalLayout(componentA, componentB).setClassName("myClass").setAlignItems(Alignment.CENTER))).

I did see various component in the directory, like fluent-vaadin-flow, but I'm a bit afraid that they will not be maintained.

Would you be interested in a PR that does the boring work of either:

  1. Change various setters to return this (this could perhaps break stuff that relies on java bean semantics).
  2. Introduce withXXX() for every setXXX() that return this.
  3. Introduce builders (aka factories in https://github.com/CNBroderick/fluent-vaadin-flow/tree/master/src/main/java/org/bklab/flow/factory)

I have no clue how big a task that is, but I'm willing to clone the repo and give it a go. But if you know upfront for whatever reason that this will be rejected I will not bother.

Best regards Jens

Legioth commented 3 years ago

I suspect the boring work of going through all components is the only easy part here (and could potentially even be automated).

Some more challenging pars:

djarnis73 commented 3 years ago

It is not that complicated (but still of course work that needs to done) to make it part of the unit testing suite to verify that all setters return a value or that all setters that return void must have a sibling withXXX(). There will probably be some special cases to handle.

I do also believe as mentioned by @HermanBovens that you can have HasStyle setters return HasStyle but then override it in implementing classes so they return their own type (did a small test locally and that is quite possible).

The implementation should of course not be a big burden to maintain.

Legioth commented 3 years ago

The challenge with subclasses goes one step deeper, with custom subclasses in the application project such as public class CustomInput extends Input. If the application developer then wants to add a withCustomSetting(String setting) method to their subclass, they again end up in a situation where they cannot do new CustomInput().withValue("foo").withCustomSetting("bar") unless they also override withValue in their own class.

This might be an acceptable tradeoff, but I'm not really sure about that.