Os 10       (dez) maus
              hábitos dos
         desenvolvedores JSF

Rafael Ponte               Tarso Bessa
http://www.rponte.com.br   http://www.tarsobessa.com
rponte@gmail.com           tarso.bessa@gmail.com
Antes de mais nada, uma
  provocação gratuita
BRUNO PEREIRA




01/01/1990         19/09/2009
RIP - REST in Peace
                 BRUNO PEREIRA




    01/01/1990         19/09/2009
Voltando ao que
  interessa...
Quem?
“Rafael Ponte”              “Tarso Bessa”
●   Desenvolvedor           ●   Arquiteto Java
●   Coordenador do          ●   Entusiasta Java e JSF
    grupo JavaSF            ●   Membro do Cejug
●   Entusiasta Java e JSF   ●   Trabalha na Dataprev
●   Consultor da
    TriadWorks
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/>
        SOLUÇÃO?
para esconder componentes
do usuário
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.
mais longo que request | mais curto que session


✔ Myfaces Tomahawk [t:saveState]
✔ Myfaces Orchestra

✔ Myfaces Trinidad [pageFlowScope]

✔ JBoss Seam

✔ JBoss Richfaces [a4j:keepAlive]

✔ etc
8º Mau hábito
Usar <redirect/> nas regras
de navegação para forçar a
mudança da URL
SOLUÇÃO?
entendam
Simplesmente
 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
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.
Apply
Restore                   Process
            Request
 View                    Validations
             Values




                          Update
 Render      Invoke
                          Model
Response   Application
                          Values
//immediate=false
private UIInput input;
//immediate=true
public 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=false
public void calcTaxes() {

    if( date.after ( otherDate ) ) {
       //calculate
    }
}
A quem recorrer?



✔ Myfaces Tomahawk [t:subform]
✔ Myfaces Trinidad [tr:subform]

✔ JBoss Richfaces [a4j:region]
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
- Callback -

 public class Bean {

     @PostConstruct
     public void initialize(){
        this.users = service.findAllUsers();
     }

     public List<User> getUsersList() {
       return this.users;
     }
 }
- Evento -

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!

Rafael Ponte                  Tarso Bessa
twitter.com/rponte   twitter.com/tarsobessa

Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)