Hi Igor,

Em 23/12/2009 20:28, Igor Vaynberg escreveu:
On Wed, Dec 23, 2009 at 12:51 PM, Ricardo Mayerhofer
<ricardo.ekm.lis...@gmail.com>  wrote:
Good discussion.

Em 23/12/2009 15:32, Igor Vaynberg escreveu:
On Wed, Dec 23, 2009 at 7:02 AM, Ricardo Mayerhofer
<ricardo.ekm.lis...@gmail.com>    wrote:

Hi Igor,
Thanks for your response. Here goes my observations:

Em 22/12/2009 14:41, Igor Vaynberg escreveu:

On Tue, Dec 22, 2009 at 5:19 AM, Ricardo Mayerhofer
<ricardo.ekm.lis...@gmail.com>      wrote:


Hi all,
We've just finished with success a wicket project for a large online
retailer. I think wicket is the best framework out there, but as any
other
project there is room for improvement. I will talk about some topics
bellow,
I hope it can help in some way.

- Separation of corcerns
I think we could get a better separation of concerns if page class were
focused more in behavior and html were more focused in display (or
view).
What I mean is, some times we have components that the main purpose is
to
add behavior, and we have to add extra markup just to satisfy wicket
1:1
mapping. Take CheckGroup for exaple, it is a component focused on
behavior,
even though we have to add a reference to it in HTML.


a redesigned CheckGroup is welcome, but that component is the
exception and not the rule.



Yes, but how do we deal with the requirement of all components having a
HTML
representation? The same happens with RadioGroup, even with wicket-1055
solved, the HTML reference is still there.

CheckGroup and RadioGroup are essentially the same thing as far as the
way they work. once you redesign CheckGroup the RadioGroup update will
be minimal.f

i dont think there is a big problem requiring every component to have
an html tag. after all wicket is a component based framework where
components represent ui which is in turn represented by html tags. the
tags also carry with them importance on nesting, so i also dont think
its a problem that wicket components carry the same importance.

I think that components should not represent UI, because if you do so you
will get a very strong coupling between both. I think it should be there to
add behavior to UI.
heh, the whole point of wicket is to build UI so there has to be coupling.

Wicket being targeted to build UI, doesn't mean its layers should be coupled. Just like the VC part of the old MVC pattern. Dispite the fact they collaborate to solve UI problems, they are loosely coupled (or not even coupled at all in the original definition).
It's mainly a philosofical difference that has many implications. For
example, if we go with the last there won't be TextArea, TextField,
HiddenField and PasswordField. Only a text field component, that represents
behavior for this kind of input.
ok. lets say there is no textarea component only a textfield. how do
we add support for attributes that textarea supports that input tags
dont, such as cols and rows. lets say i have a requirement to control
those pragmatically.

if we have no textarea component then i have to use attribute
modifiers or some other means to add the cols and rows attributes, but
by doing so any knowledge of how they work and what constraints they
have is completely decoupled from the component - which is not a good
thing because you have traded coupling for encapsulation. the very
basic principal of OOP is that your data is coupled to the behavior
that modifies the data - an Object.
This architecture favors decoupling between java and HTML. Rows and cols are a purely view concern, so it shouldn't be handled in page class. If there's a situation where it necessary to change textarea size the best thing to do IMO is to append a class, so the designer is free to choose the most appropriate display information and still can choose the most appropriate form element to the current job (textarea or text input). With the current architeture one may think that it's ok to put these things in java, for example, extending TextArea and hardcoding this information.

Regarding other attributes, I don't recall one that is only appliable to a specific tag and requires encapsulation. This situation might happen, but I would say YAGNI for now.

The same for buttons and links.
these are all simple components. what happens when we talk about
components that compose others? such as the DataTable that composes
Items that compose user's other Components that represent rows?

You also solve checkgroup and radiogroup useless tag problem, and open doors
for components that the main purpose is to add behavior to the page, even if
not directly related to one specific tag.
lets see a concrete way of how this will work. do we now have
something in Component hierarchy that is an "non-rendered" component?
how do all the current cascades and visitors work with this?

In my limited knowlege I would say just like rendered components.
That's the very example you gave, a webmarkupcontainer that controls other
components visibility. There is no need to map the container to HTML.
in some cases maybe not, but in most cases that will be non-functional
markup that is under this container that you also want hidden - after
all we are dealing with UI. without a container attached to the tag do
you now have to make those nonfunctional fragments of markup into
components so they can also be hidden?

Also if we loose this coupling we can change java and html in a more
independent way, resulting in more flexibility.
by losing coupling you also lose a lot of data - namely the nesting -
that is extremely useful in a lot of cases. eg - which form does this
textfield belong to?
I think it's ok to have nesting where it provides important information for wicket processing, like forms. This happens often when we're dealing with behavior. The problem IMO, is to have nesting just to replicate HTML structure. This remembers me DRY principle (pragmatic programmers). It's worth reading.

A excerpt from Dave Thomas interview:
If you have more than one way to express the same thing, at some point the two or three different representations will most likely fall out of step with each other. Even if they don't, you're guaranteeing yourself the headache of maintaining them in parallel whenever a change occurs. And change will occur. DRY is important if you want flexible and maintainable software.
come up with a list of usecases where this is inconvenient and if
there are a lot we can address them. but i cant really see many past
Check/RadioGroup components.
^ too bad you have skipped that one :)

When creating composite input fields (like date), the usual way is to
create
a panel even if you are not interested in reusability. A interesting
aproach
is to insert a hidden text field in HTML mapped to a component that
controls
other components input. It makes easier to integrate with designer and
to
preview in browser. If we didn't have this limitation the hidden input
would
not be necessary and the development of behavior focused components
would
be
easier.


i dont really understand this..the usual way would be to extend a
FormComponentPanel, not a Panel. are you saying that because the Panel
derivatives are just a<div>      in the markup it makes it difficult for
the designers?



You're right, I meant FormComponentPanel. I think it would be better not
being constrained to have a separate markup just because server side
processing will be different. After all in HTML terms, a composite input
is
the same as a single input.

this has nothing to do with the difference in server-side processing,
this is more a design choice that promotes good reuse. lets say you
create a compound component that has two select boxes. if you do not
make it into a panel that means everywhere you use it you *have* to
know what kind of markup to put in, what the wicket:id values are for
the two select boxes that it uses, etc. in the future if you modify
this component to have a container around the two select boxes you now
have to find every place in your project where you used this component
and add the container. sounds like pita to me.


We usually start simpler and if required by another piece of functionaly, we
start generalizing and extracting components. Even if you know from the
start you need a reusable components, it's nice to take baby steps, do the
simpler, make it work, and then extract it.
It's great to have the option of getting a reusable composite component, but
the problem is that there is no way of doing different.
sure there is and its under 10 lines of code

class formcomponentcontainer extends formcomponent {
        protected void onComponentTag(final ComponentTag tag)
        {
                super.onComponentTag(tag);
                tag.remove("name");
                tag.remove("disabled");
        }
}

now you have a webmarkupcontainer version of the formcomponentpanel
which will use inline markup.
Looks interesting. To use this solution do I have to place a extra tag in markup? If so, the tag would be there just because it has to be there :)
Another example of unecessary coupling IMO is
that text area and input text fields are mapped to different components,
even behaving the same.
Even if there are internals when manipulating one or another, I think it
should be handled by wicket because for the programmer it makes no
difference.

agreed. we already do this with links and buttons. my guess is that it
has never bothered anyone enough to create an rfe.


One thing that bothers me is when our designer move things around in
HTML
and we get "added a component in code but forgot to reference it in the
markup" error, because of component hierarchy. Html tags position is a
view
problem not a behavior problem, so why bother in java?


it *is* a behavior problem. markup is what drives the rendering order
so if you move things around and change the nesting order of
components then you can have a component that is a child of another
render *before* the parent which will cause things to go seriously out
of whack.

in my company the designers understand that they cannot change the
nesting of tags with wicket:id attributes, it took an hour to explain
it to them, and we have not had any problems since. in practice, there
is no need to do that often anyways...



IMO learning how to deal with a restriction, isn't better than removing
that
restriction. Even if it doens't happen often, I would be happier if it
never
happens :)
Render order seems a wicket internal concern to me not a business or
application behavior concern.

render order has to be defined somewhere. it can either be defined in
the markup or it can be defined in your code. if it is defined in your
code by the sequence of add() calls then every time the designer wants
to move anything around (even sibling components) you will have to
change the code. with the render order coming from markup this
restriction is only when the nesting of components changes. which one
seems more restrictive to you?

None of them seem good to me. I don't know the solution but I would be glad
to help to come out with one.
we are all ears.

it is nice to have a cop-out of "this is not a business concern", but
that doesnt really mean anything when discussing this does it? when
working on any application you are always restricted by the technology
you are using whether it be your web framework, your application
server, your database, your operation system, your server, your
backbone, etc..


Another issue, is when we want to change the class of a div, for
example,
and have to change our whole page hierarchy in java, just to manipulate
that
tag.


you dont have to change the hierarchy, just make the component
attached to that div a "transparent resolver" by overriding
isTransparentResolver() and returning true.



So I think a hierarchy more focused on components behavior (for example
taking care of inherited models and inputs), rather than tags position
in
HTML would be better. This would make wicket more flexible and easier
to
work with.


once again, this is only a problem when you change the *nesting* of
components. if a component can be safely moved outside the parent,
then why is there a nesting to begin with? why arent the two
components siblings? the *nesting* is usually there *because* there is
a functional requirement.

here is a simple usecase:

webmarkupcontainer admin=new webmarkupcontainer("admin") { isvisible()
{ return user.isadmin(); }};
admin.add(new link("delete") {...});

the code is pretty much self-explanatory, now the designer takes the
delete link and moves it ouside the wicket:id="admin" tag. in your
vision this would work, but now the designer has completely
circumvented security the developer has put into place.



They have a functional relationship, so no matter where delete link is in
HTML, it should be invisible. This has a aditional advantage that I do
not
need to map admin to HTML, and can group another admin functions in the
same
component, even if they're scattered.

and how would you define this "functional" relationship. it is very
convenient to be able to control certain things such as visiblity and
enabled state on a parent in order to be able to easily propagate it
to children.

we are always ears for new good ideas, but it takes more then "it
should work like this".

You're right, I'm talking about ideas here, but as above I would be glad to
help if there is some acceptance of those or openness to discuss it further.
come up with something concrete, in code, that works. talk is cheap. i
have been working with wicket for a long time and i dont see a better
way of dealing with this particular problem. maybe i have been staring
at it for too long and have tunnel vision. maybe someone can come up
with a better way - which i would warmly accept. but no one has yet
done so. as far as anyone has got was to say "there is a better way".
thats nice.
I've been working for a couple of months on some ideas I presented. We've used in 2 projects and the results were very good. I couldn't acomplish too much, but it was a good start. It would be easier if more strategy + dependency injection were used in wicket. I had to change some classes and remove some finals.

I think talk is important, because even if wicket don't get changed, we can open some extension points that would allow deeper changes in the framework itself. If there's no will of doing so, it would be wasted effort.
- Too many finals modifiers
It's hard for a API or framework designer to foresee all uses and
unxepected
situations its users may face in day to day development. Final
modifiers
places a additional challenge when facing these situations. In project
were
deadlines are in place, there is little room for submiting a request
and
waiting for a new version to be released. Furthermore, unfortunately,
it's
not possible to mock final methods making it harder sometimes to test
wicket
related classes/components. What we had to do internally, is to have
our
own
version of wicket, mainly to remove final modifiers when necessary, a
clear
violation of open/closed principle.


there is a trade off here. the final modifiers allow us to change
things below without breaking the api because final methods do not
expose a contract. when we make a code change inside a final method we
do not have to think about all the users out there who might have
potentially overridden the method in their apps and we have to make
whatever change backwards-compatible.

in short, the upgrade path with final methods looks like this:

1.4.0,1.4.1,...,1.4.8,1.4.9

and the path without final methods would look like this:

1.4.0,1.4.1,1.5.0 (api break),1.5.1, 1.6.0 (api break), 1.7.0 (api
break)

and because we are changing contracts the api break would most likely
not be compile time, so you would have to scour through release notes
and see if you have overridden any of the specified methods that now
work differently.

which one is better?



Being able to overcome a problem is a need required by the current
project,
which final may impose a additional challenge.
Upgrades, on the other hand, are usually planned process, in which are
considered possible problems or API changes.

so now to get almost any bug fix you have to recompile, change code,
and redeploy the entire application. that seems like a highly risky
proposition. it basically means you can never really retire an
application that is feature-complete and simply drop new wars in to
get bug fixes, you always have to have active development on it. i
dont think many people will buy this approach.



I think spring is a good example in this area. It has a pretty good
backward
compatibily, and use very few finals.

you are comparing apples to oranges. you do not write your application
"in" spring. spring is all about staying out of your code, so of
course they can do whatever the hell they want because they have very
few public apis. wicket, on the other hand, is opposite. in wicket
most apis *are* public and you use them in your code. we do not
provide interfaces for the same reason we use final methods, we do not
want to lock ourselves into a contract.


Spring also has Spring MVC and spring web flow as part of it. If I remember
correctly Rod Johnson, is a advocator of avoiding static, singletons and
finals.
once again, spring mvc works under the same principal as spring, you
configure your controllers outside the code via spring, just like any
other bean. other then that the surface area of the api is
infinitesimally smaller when compared to wicket. you have your
request, response objects, and not much more beyond that.

Wicket is the only framework I remember that uses final
probably because the wide majority of java developers out there dont
know that the final keyword exists

Ok, wicket is unique and/or others don't know java.
as a aproach for
backward compatibility. That makes me wonder if there is a real problem of
not doing so and if there is alternatives.
we do not use final for backwards compatibility, we use it to prevent
ourselves from being locked into a contract, which offers us
tramendous flexibility when we need to refactor how something works.

you say that contracts should only be exposed via interfaces - that is
a nice notion. in reality, any non-final method *is* a contract.
therefore, by your thinking, any class that has a non-final method
should be backed by an interface... :)

another point is that neither one of us has any visibility into the
internal development of spring. you are making this observation seeing
only the final product, but do you know how many times a core spring
developer thought to himself: damn, if only this method was final i
could throw in this new cool feature into the next minor release, or
better yet, damn if only this method was final i could fix this bug in
the next minor release instead of the next major one.


About contracts, I think that they should be specified in terms of
interfaces, not concrete classes. If you depend on concrete classes, it's
natural that they evolve and may break your integration.

so its ok if the next minor jdk update changes the api of String?
thats a concrete class...


I don't remember JDK using many finals :)
maybe if it did then we would have had first class functions, methods,
closures, and proper generics instead of having to work with a
language that feels so very outdated :)

Scalla and Grails has some of those, and I haven't seems many finals either. This leads me to conclude that java didn't evolve for the same reason wicket keeps final, fear of breaking contracts.
Wicket offers no stateless ajax


we may work on a stateless ajax in the future, for now it is really
not that hard to use a third party library.



and often changes HTML id, which makes
harder to integrate with a 3rd party ajax framework.


wicket only changes ids that belong to components, and that is only to
make sure they are unique. wicket does , however, offer a way to
override the id to whatever you want by calling setMarkupId(..)

the proper way to integrate with third party libraries is to pass them
ids by calling getmarkupid()



Many of things I raised (or all of them) have solutions in wicket. But I
think it's best when the framework solves the problem, rather than doing
it
myself. That's why we use frameworks in the first place.

yes, it would be great to have an easy button. unfortunately every
application out there is different and there is no way we can provide
a set of defaults that will work for everyone out there.

we strive to hit the point at which "easy things are easy and hard
things are possible".


I can't see how a application would benefit of having its HTML ID changed if
there isn't the same identifier another place in the document. Sometimes I
don't think it's about solving everyone problem, but about keeping possible
problems away.
so we should make the changing of ids non-deterministic. yes, that
sounds like a great improvement. so you write your application and
hardcode your ids in markup and in all the css and javascript. a month
from now someone adds a third party component, or another instance of
non-third party component into the page and creates an id collission.
suddenly all your javascript and css breaks. now you have to go
huntdown and see why the hell everything is broken.

where as if you did the thing you are forced to do now: pass the
wicket-generated id to all the javascript everything would work just
fine. wicket is component-oriented, that means one of the msot
important things it does is to ensure encapsulation of
component-related resources which in turn allows components from all
the different places to play well together and allows them to be
easily composed.
Considering that this is not related to the other topics, I think it's worth putting it into another thread.

Regarding, the other comments, think about it Igor. I think we can greatly improve wicket.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to