14. listopadu 2008

JSF vs. Tapestry - tentokrát AJAX

Zase trochu přileju olej do ohně, tentokrát se podíváme na jednoduchý AJAX příklad. Opět začneme na blogu Jima Driscolla, který napsal A simple Ajax JSF 2.0 example. Při pohledu na tento příklad se opět nemohu ubránit dojmu, že vývoj stránek je v JSF opravdu děs, no posuďte sami (pro jednoduchost ukazuji pouze to co je zajímavé a ne celou stránku):

<h:body>
<h:form id="form1" prependId="false">
<h:outputScript name="ajax.js" library="javax.faces" target="head"/>
<h:outputText id="out1" value="#{count.count}"/>
<br/>
<!-- Increment the counter on the server, and the client -->
<h:commandButton id="button1" value="Count"
onclick="javax.faces.Ajax.ajaxRequest(this, event, {execute: this.id, render: 'out1'}); return false;"/>
<br/>
<!-- Resets the counter -->
<h:commandButton id="reset" value="reset"
onclick="javax.faces.Ajax.ajaxRequest(this, event, {execute:'reset', render: 'out1'}); return false;"
actionListener="#{count.reset}"/>
</h:form>
</h:body>
A jak to samé uděláme v Tapestry nám ukáže Howard L. Ship na svém blogu v příspěvku Tapestry 5 Ajax Screencast. Šablona bude:
<body>
<t:zone t:id="output">${index}</t:zone>
<p>
<t:actionlink t:id="increment" zone="output">increment</t:actionlink>
</p>
<p>
<t:actionlink t:id="reset" zone="output">reset</t:actionlink>
</p>
</body>
A nyní přistupme k Java kódu, ten je v JSF malinko jednodušší, protože definuje pouze beanu s hodnotou počítadla:
@ManagedBean(name = "count")
@SessionScoped
public class Count {
Integer count = 0;

public Integer getCount() {
return count++;
}

public void reset(ActionEvent ae) {
count = 0;
}
}
A nyní ta "složitější" Java třída, tedy Tapestry verze:
public class Index {
@Property
@Persist
private int index;

@InjectComponent
private Zone output;

Object onActionFromIncrement() {
index++;
return output.getBody();
}

Object onActionFromReset() {
index = 0;
return output.getBody();
}
}
Navíc zde máme definováno co se má měnit po provedení AJAX requestu, toť celá komplikace navrch.
Pro mě je to stále jasné, JSF je špatná volba proto, že je hrozně komplikované a těžko mě někdo bude přesvědčovat o opaku.
PS. Letěl okolo mě moc hezký článek o porovnání Wicket a JSF s názvem A Wicket user tries JSF. Ukázky, které jsou tam uvedeny na mě budí dojem, že Tapestry je kombinací toho dobrého z obou těchto světů: jednoduchou Java část z JSF a jednoduché šablony z Wicket.

13 komentářů:

Anonymní řekl(a)...

nevim jak v cistem jsf, ale kdyz pouziju RichFaces tak se nic takoveho delat nemusi a ten kod vypada stejne jako bych nepouzival AJAX, ale celkove musim uznat, ze pouzivat JSF je vopruz

Anonymní řekl(a)...

RichFaces ma ale uplne vlastni proccessor (A4J) na Ajax requesty. A ma ho uz od JSF 1.1. Takze pri pouziti Richfaces dochazi k velkemu zkresleni pohledu na JSF jako takove.

Unknown řekl(a)...
Tento komentář byl odstraněn autorem.
Anonymní řekl(a)...

Muzes trochu rozvest ten 'vlastni procesor na requesty' ?

A4J "pouze" rozsiruje a deleguje na standardni JSF komponenty (state manager / view handler, a a4j servlet filter, ktery (pokud je mi znamo) resi odkazy na resourcy, a push check (HTTP HEAD) requesty.

Rozsireni lifecycle resp. jednotlivych komponent je koser - specifikace JSF jej predpoklada. V cem presne se tedy zkresluje pohled na JSF ?

Unknown řekl(a)...

achjo, nejlepsi je se vyjadrovat k necemu co jeste neni hotove (jsf2.0) a navic Jim Driscoll jasne pise v tom clanku ze finalni podoba tohoto ajaxoveho prikladu v jsf2.0 bude jednodussi. nechte si laskave svoje vyplody az bude spravna doba neco porovnavat.

Anonymní řekl(a)...

Martin: nejlepsi je, ze Tapestry tym si na zacatku prihreje svoji polivcicku.

Ne uplne cistymi metodami, clanek http://tapestryjava.blogspot.com/2008/11/simple-jsf-20-component-vs-tapestry.html take taktne nezminuje, ze v Tapestry metadata pro tooly nejsou a porovnava jabka (java anotace v kodu) a hrusky (sablonu ktera ma jako cil moznost NEPSAT javu).

A bloggeri se toho chyti. Takhle se bohuzel vytvari "odborne mineni".

Docela mne to mrzi, protoze z cteni Tapestry kodu jsem k Mr. Shipovi pojal urcitou uctu - podpasovky bezne v marketingu nema Tapestry tym vubec zapotrebi.

Anonymní řekl(a)...

A co takhle wicket way...


<html>
  <body>
    <a href="#" wicket:id="link">Inkrementuj pocitadlo</a>   
    <span wicket:id="label">[tento text bude nahrazen]</span> times.   
  </body>
</html>






public class LinkCounter extends WebPage { 
    private int counter = 0;               
    public LinkCounter() {
        add(new Link("link") {        
            @Override                 
            public void onClick() {   
                counter++;            
            }                         
        });
        add(new Label("label", new PropertyModel(this, "counter"));   
    }
}

Anonymní řekl(a)...

wicket way: Dost dobry, akorat jsi z prikladu http://wicket.apache.org/exampleajaxcounter.html zapomnel okopirovat prave tu cast, ktera dela AJAX :) protoze Link componenta nedela AJAXove requesty.

Ne ze by byla nejak vyrazne slozitejsi.

Jira řekl(a)...

Zřejmě jsem to již někde psal, ale nedá mi to. Wicket je miliónkrát lepší než JSF, ale nějak je mi proti mysli vytvářet strukturu komponent nejenom v HTML šabloně, ale i v podpůrné třídě.

Anonymní řekl(a)...

> nějak je mi proti mysli vytvářet strukturu komponent nejenom v HTML šabloně, ale i v podpůrné třídě

O vyhodach ci nevyhodach imperativneho (Wicket) a deklarativneho (Tapestry) programovacieho modelu by sa dalo diskutovat cele hodiny pretoze kazdy z nich ma svoje plusy a minusy.

V prospech imperativneho pristupu hovori najma vacsia flexibilita, typova kontrola a refaktorovatelnost kodu. Na druhej strane silnymi strankami deklarativneho pristupu su lepsia otimalizovatelnost a produktivita vyvoja pretoze vyzaduje podstatne mensi objem kodu k realizacii urcitej funkcionality.

Wicket so svojim imperativnym pristupom bude urcite viacej sediet ludom so Swing backgroundom. Deklarativny Tapestry model zase urcite viacej padne do ruky klasickym web developerom, takze do uvahy je potrebne brat aj strukturu a skusenosti developerov ktorych mate k dispozicii.

Jira řekl(a)...

Jistě jsem si toho vědom, že taková porovnání nemohou udělat závěr, ale mohou pouze nabídnout rozdíly a každý jedinec se pak sám musí rozhodnout, který přístup mu víc vyhovuje.

Podle mě zásadním rozdílem mezi Wicket A Tapetry je existence stromu komponent v sessioně. Tj. ve Wicket je možno tento strom měnit a mít ho dynamický. V Tapestry to nejde, protože si strom vždy znovu vytváří (např. při zpracování requestu).

Výhodou statického stromu je menší zatížení sessiony a z toho plynoucí lepší škálovatelnost na více strojů.

Anonymní řekl(a)...

> Výhodou Tapestry je menší zatížení sessiony a lepší škálovatelnost

To je pravda. Vyplyva to zo stavovosti Wicketu kde kazda obrazovka v browsery je na serverovej strane reprezentovana plnym komponentovym stromom umiestnenym v session, co za urcitych extremnych okolnosti (aplikacia s velkym poctom komplexnych obrazoviek + velka zataz aplikacie + replikacia session) moze sposobit vazne problemy so skalovatelnostou. Na druhej strane toto riesenie ma vyhody v jednoduchosti, zrozumitelnosti a nativnej podpore pre "back button" navigaciu.

Pre potreby aplikacii s vysokymi narokmi na skalovatelnost je urcite vyhodnejsie pouzit Tapestry kde je stav oddeleny od komponentoveho stromu, ktory preto moze byt poolovany a prepouzity medzi roznymi uzivatelmi (co vyrazne setri zdroje applikacneho serveru).

Anonymní řekl(a)...
Tento komentář byl odstraněn administrátorem blogu.