Hi,
On 1/28/22 9:18 AM, Martin Terra wrote:
pe 28. tammik. 2022 klo 10.12 Matthias Metzger (noobyma...@yahoo.de.invalid)
kirjoitti:
Hi,
On 1/28/22 1:47 AM, Martin Terra wrote:
to 27. tammik. 2022 klo 23.00 Matthias Metzger
(noobyma...@yahoo.de.invalid)
kirjoitti:
Hi,
On 1/27/22 5:52 PM, Martin Terra wrote:
Hi!
I am curious how this would compare to a declarative ui.
You would define your ui in pojo, almost like swing, and then you have
a
generic rendering helper/factory layer tailored to your project, which
then
handles *all* the nitty gritty stuff.
Only when you create a new feature, would you worry about its targets
etc
which you would implement onto the rendering helper/factory layer.
There might be parts of such structure that could be reusable across
projects.
Would this overcome the need for DSL, or would you consider it DSL as
well?
Disclaimer: The following is just my opinion.
I think, something like this would be a DSL, because it's a language
specifically designed to describe UIs. Internally, there might even be
two DSLs. One for modeling and describing a UI as pojos, XML, JSON or
functions (in this specific example it's the sealed interface Html) and
one for creating instances of these things (what you see as div {
text("Hello") }). And then there might be other DSLs for specific
frameworks.
Creating a DSL for describing UIs generally and trying to abstract away
Wicket specifics, to then write some Wicket specific renderer again is
something I have tried in the past and I just don't see the practical
value, since it just makes the implementation much more complex. But
maybe I misunderstood you.
For us the benefit is two-three-fold. First, I'd say
all formcomponents/labels in an ui follow patterns which can be
canonized.
Second, reuse.
You can use a label on a panel and you can use the same label in a table
to
render (or search) the same data. You can also use it to render a column
in
a spreadsheet. Goal is to never implement a label twice.
Or you can use a command item in a menu (or in a button on a panel) to
access the same action. Goal is to never implement an action twice.
Lastly, there are efficiency ganis from centrally tested components which
now furthermore can more easily be automatically tested as they have
standard types and standard expected outcomes.
No more "I forgot to handle that special case again" when you are reusing
the same component type you once already solved.
If you have a new developer, they can start by using the existing
components or creating similar ones. No need to explain wicket potholes
"ah, this is a wicket trick, here you need to do this first before doing
that, and you need to remember this....and in this special case...do that
don't do that" instead they will pick the closest one from library and
see
all implementation requirements or hooks it has (optional and required
implementations/extensions).
I am not sure, I am following here. To clarify: You are arguing, that
the DSL I've shared should not be done like that, because it would be
better to solve the problem of a declarative, generic UI, that can be
"compiled" (in the sense of factories/adapters) down to Wicket?
Well, there might be some (cross-project) reusable paradigms and patterns
and templates, which we could call dsl.
I'm not arguing, just bringing up an alternative approach for
consideration, maybe they could co-exist as well.
Gotcha! So, to answer your question from the beginning: How does a
declarative UI compare to the approach I shared (whether we call it a
DSL or something else). I think a declarative UI would just be a
generalization of the approach I took here. They might co-exist or the
this approach could iteratively be generalized. Not sure, how good that
would work though, since especially the Ajax-Handling in Wicket is
probably difficult to abstract. Phoenix LiveView might be an inspiration
here.
However, as far as I can see, when it comes to actually implementing the
adapters - the nitty gritty, as you rightly called it - (which is
essentially, what I am doing here), the same questions would come up in
both approaches:
- Is using the IMarkupResourceStreamProvider and the
IMarkupCacheKeyProvider the way to go or are there any other ways? For
example, would it be wise to subclass MarkupContainer or Component to
implement this?
- Are there performance/caching/framework problems if you re-render the
markup and components on every request?
- Is mitigating that, by just rendering the markup once per
component/page viable or would that lead to a MarkupCache growing
linearly with the amount of rendered pages and therefore explode the
memory usage?
Or am I missing something? I don't see, how a declarative UI would
circumvent these questions. Except, if there was a compile step, which
would compile it down to Wicket code.
Best regards
Matthias