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. listopadu 2008

Co to je čitelný kód aneb Literate Programming

Obdivuji lidi co mají tu vlastnost, že dokáží naprosto přesně vyjádřit to co ostatní jenom tuší (řada ani to ne). Teď jsem zase narazil na jednoho takového člověka, kterým je Donald E. Knuth, jenž mě dostal svým spiskem o Literate Programming. Nosnou myšlenkou, která mne zaujala je:

Nesnažme se svým programem počítači sdělit co má dělat. Snažme se programem vysvětlit druhým programátorům, co chceme aby počítač dělal.

To je přeci ono. Nepíšeme program jenom proto, aby dělal co má dělat, ale také proto, aby ho dokázal někdo udržovat (to je ten člověk, kterému vysvětluje, co chceme aby počítač dělal).
Již dlouho jsem náš vývojový proces přizpůsoboval této myšlence, možná jsem ji měl někde zakopanou v podvědomí, ale nedokázal jsem ji tak krásně vyjádřit.

3. listopadu 2008

JSF vs. Tapestry - jak jednoduché je dělání komponent

Opět jsem narazil na velmi zajímavý blog, který porovnává složitost vytváření komponent v JSF 2.0 a Tapestry 5 ("Simple" JSF 2.0 Component vs. Tapetry).
Samotného mě takové porovnání již dlouho zajímalo, protože jsem se o JSF přestal zajímat někdy okolo verze 1.0, přišlo mi zkrátka moc složité a komplikované. Navíc mělo veliké problémy na úrovni integrace s JSP (to už je snad minulost). Takže pokud se někdo nechce koukat na originál, pak vězte, že napsat komponentu v JSF, která vypíše text na žlutém pozadí je realizováno následující komponentou:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>This will not be present in rendered output</title>
</head>
<body>

<composite:interface name="yellowOut"
displayName="Very Basic Output Component"
preferred="true"
expert="false"
shortDescription="A basic example">
<composite:attribute name="value" required="false"/>
</composite:interface>

<composite:implementation>
<h:outputText value="#{compositeComponent.attrs.value}" style="background-color: yellow"/>
</composite:implementation>
</body>
</html>
Uf. To je skoro jako těžká dřina. V Tapestry stačí velmi krátká třída:
public class Out {
@Property
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String value;
}
A ještě kratší šablona:
<span style="background-color: yellow">${value}</span>
Takže já mám zase jasněji v tom, co je lepší používat.