os 10 maus hábitos dos desenvolvedores jsf
DESCRIPTION
Apresentação sobre Maus Hábitos em JSF realizada no JustJava '09.TRANSCRIPT
Os 10 (dez) maus hábitos
dos desenvolvedores JSF
Rafael Pontehttp://[email protected]
Tarso Bessahttp://[email protected]
Quem?
● Desenvolvedor● Coordenador do
grupo JavaSF● Entusiasta Java e
JSF● Consultor da
TriadWorks
“Rafael Ponte”● Arquiteto Java● Entusiasta Java e
JSF● Membro do Cejug● Trabalha na
Dataprev
“Tarso Bessa”
JSF tenta encapsular toda a complexidade no desenvolvimento web com Java
A maioria dos desenvolvedores web que já trabalharam ou trabalham com algum framework “action-like” acabam tendo grandes dificuldades ao desenvolverem com JSF.
Criando-se então maus hábitos..
10º Mau hábito
Usar <c:if/> ou <c:when/> para esconder componentes do usuário
<c:if test=”#{bean.admin}”><h:dataTable var=”row”>
<h:column>...
</h:column></h:dataTable>
</c:if>
Usar <c:if/> ou <c:when/> para esconder componentes do usuário
SOLUÇÃO?
Utilizar o atributo rendered dos
componentes para escondê-los do usuário
<c:if test=”#{bean.admin}”><h:dataTable
rendered=”#{bean.admin}”><h:column>
...</h:column>
</h:dataTable></c:if>
9º Mau hábito
Usar “stateless” EL no atributo rendered em um componente que dispare eventos
<h:commandButton value=”Salvar” action=”#{bean.salvar}” rendered=”#{bean.admin}” />
SOLUÇÃO?
Garantir a avaliação consistente da EL entre requisições.
session?
O uso indevido ou exarcebado da session é prejudicial para a aplicação.
✔ Myfaces Tomahawk [t:saveState]✔ Myfaces Orchestra✔ Myfaces Trinidad [pageFlowScope]✔ JBoss Seam✔ JBoss Richfaces [a4j:keepAlive]✔ etc
mais longo que request | mais curto que session
8º Mau hábito
Usar <redirect/> nas regras de navegação para forçar a mudança da URL
SOLUÇÃO?
Simplesmente entendam como funciona um
REDIRECT
7º Mau hábito
Alterar o estado de algum componente no lado cliente [browser] através de javascript e esperar que isso seja “entendido” pelo JSF
Firebug
SOLUÇÃO?
Alterar o estado do componente no lado servidor via AJAX e
re-renderizar o componente
6º Mau hábito
Utilização demasiada de parâmetros de request e desenvolvimento voltado a "chave primária"
<h:dataTable value="#{users}" var="user"> <h:column ...>
<h:commandLink value="X" action="#{bean.remove}" >
<f:param name="id" value="#{user.id}"/> </h:commandLink>
</h:column></h:dataTable>
public void remove(){ Integer id = new Integer( facesContext.getExternalContext(). getRequestParametersMap(). get(“id”) );
User user = search(id); if(user != null){ ... }}
SOLUÇÃO?
Pensar mais orientado a objetos e deixar com que os
componentes troquem objetos e não “chaves
primárias”
<h:dataTable value="#{users}" var="user"> <h:column ...>
<h:commandLink value="X" action="#{bean.remove}" >
<f:setPropertyActionListener value="#{user}" target="#{bean.user}"/> </h:commandLink>
</h:column></h:dataTable>
public void setUser(User user){ this.user = user;}
public void remove(){ if(user != null){
// ... }}
É fundamental implementar os métodos equals() e hashCode()das entidades da aplicação.
5º Mau hábito
Usar o valor do submittedValue de um componente como se fosse o valor real do componente.
RestoreView
ApplyRequest Values
ProcessValidations
RenderResponse
InvokeApplication
UpdateModelValues
//immediate=falseprivate UIInput input;
//immediate=truepublic void calcTaxes(ActionEvent e) { String dateStr = (String) input.getSubmittedValue(); Date date = convertDate ( dateStr );
if( date.after ( otherDate ) ) { //calculate }}
SOLUÇÃO?
Dividir o formulário em subforms
private Date date;
//immediate=falsepublic void calcTaxes(ActionEvent e) { if( date.after ( otherDate ) ) { //calculate }}
✔ Myfaces Tomahawk [t:subform]✔ Myfaces Trinidad [tr:subform]✔ JBoss Richfaces [a4j:region]
A quem recorrer?
4º Mau hábito
Implementam o próprio mecanismo de SEGURANÇA
public class LoginPhaseListener implements PhaseListener {
//on RESTORE_VIEW public void afterPhase(PhaseEvent e) { if( !isLoggedIn() && !isLogin() ){ //navigate to login page } }}
SOLUÇÃO?
Utilizem um framework especializado
Usar /faces/* ou *.jsf quando se tem páginas em xhtml pode levar a uma exposição do código fonte.
3º Mau hábito
Paginação de registros na session
Uma das melhores maneiras de matar a escalabilidade da aplicação é a utilização indiscriminada da session
SOLUÇÃO?
Paginação sob demanda
2º Mau hábito
Efetuar consultas de maneira
INEFICIENTE
<h:dataTable value="#{bean.usersList}" var="user">
<h:column ...> ...
</h:column></h:dataTable>
public class Bean {
public List<User> getUsersList() { return service.findAllUsers(); } }
SOLUÇÃO?
Usar consultas em eventos ou
callbacks
public class Bean {
@PostConstruct public void initialize(){ this.users = service.findAllUsers(); }
public List<User> getUsersList() { return this.users; }}
public class Bean {
public void search(ActionEvent e){ this.users = service.findUsers( … ); }
public List<User> getUsersList() { return this.users; }}
1º Mau hábito
1º -e o pior- Mau hábito
JSF LIFECYCLE
JSF LIFECYCLE
A maioria dos desenvolvedores NÃO
entendem
JSF LIFECYCLE
SOLUÇÃO?
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
Entendam o ciclo de vida
Concluindo..
Perguntas?
Obrigado!twitter.com/rponte
twitter.com/tarsobessa