Successfully reported this slideshow.
Os 10
          (dez)
    maus hábitos
  dos desenvolvedores JSF

Rafael Ponte               Tarso Bessa
http://www.rponte...
Quem?
“Rafael Ponte”          “Tarso Bessa”
●   Desenvolvedor       ●   Arquiteto Java
●   Coordenador do      ●   Entusia...
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 d...
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:da...
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 Tr...
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”
p...
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}" >...
public void remove(){
  Integer id = new Integer(
  facesContext.getExternalContext().
      getRequestParametersMap().
  ...
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}" >...
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




 ...
//immediate=false
private UIInput input;

//immediate=true
public void calcTaxes(ActionEvent e) {
   String dateStr = (Str...
SOLUÇÃO?
Dividir o formulário
   em subforms
private Date date;

//immediate=false
public void calcTaxes(ActionEvent e) {

    if( date.after ( otherDate ) ) {
       ...
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 ...
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 class Bean {

    public void search(ActionEvent e){
       this.users = service.findUsers( … );
    }

    public ...
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
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSF
Upcoming SlideShare
Loading in …5
×

Os 10 Maus Hábitos dos Desenvolvedores JSF

9,544 views

Published on

Apresentação sobre Maus Hábitos em JSF realizada no JustJava '09.

Published in: Technology
  • Be the first to comment

Os 10 Maus Hábitos dos Desenvolvedores JSF

  1. 1. 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
  2. 2. Quem? “Rafael Ponte” “Tarso Bessa” ● Desenvolvedor ● Arquiteto Java ● Coordenador do ● Entusiasta Java e grupo JavaSF JSF ● Entusiasta Java e ● Membro do Cejug JSF ● Trabalha na ● Consultor da Dataprev TriadWorks
  3. 3. JSF tenta encapsular toda a complexidade no desenvolvimento web com Java
  4. 4. A maioria dos desenvolvedores web que já trabalharam ou trabalham com algum framework “action-like” acabam tendo grandes dificuldades ao desenvolverem com JSF.
  5. 5. Criando-se então maus hábitos..
  6. 6. 10º Mau hábito
  7. 7. Usar <c:if/> ou <c:when/> para esconder componentes do usuário
  8. 8. <c:if test=”#{bean.admin}”> <h:dataTable var=”row”> <h:column> ... </h:column> </h:dataTable> </c:if>
  9. 9. Usar <c:if/> ou <c:when/> SOLUÇÃO? para esconder componentes do usuário
  10. 10. Utilizar o atributo rendered dos componentes para escondê-los do usuário
  11. 11. <c:if test=”#{bean.admin}”> <h:dataTable rendered=”#{bean.admin}”> <h:column> ... </h:column> </h:dataTable> </c:if>
  12. 12. 9º Mau hábito
  13. 13. Usar “stateless” EL no atributo rendered em um componente que dispare eventos
  14. 14. <h:commandButton value=”Salvar” action=”#{bean.salvar}” rendered=”#{bean.admin}” />
  15. 15. SOLUÇÃO?
  16. 16. Garantir a avaliação consistente da EL entre requisições.
  17. 17. session?
  18. 18. O uso indevido ou exarcebado da session é prejudicial para a aplicação.
  19. 19. mais longo que request | mais curto que session ✔ Myfaces Tomahawk [t:saveState] ✔ Myfaces Orchestra ✔ Myfaces Trinidad [pageFlowScope] ✔ JBoss Seam ✔ JBoss Richfaces [a4j:keepAlive] ✔ etc
  20. 20. 8º Mau hábito
  21. 21. Usar <redirect/> nas regras de navegação para forçar a mudança da URL
  22. 22. SOLUÇÃO?
  23. 23. entendam Simplesmente como funciona um REDIRECT
  24. 24. 7º Mau hábito
  25. 25. Alterar o estado de algum componente no lado cliente [browser] através de javascript e esperar que isso seja “entendido” pelo JSF
  26. 26. Firebug
  27. 27. SOLUÇÃO?
  28. 28. Alterar o estado do componente no lado servidor via AJAX e re-renderizar o componente
  29. 29. 6º Mau hábito
  30. 30. Utilização demasiada de parâmetros de request e desenvolvimento voltado a "chave primária"
  31. 31. <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>
  32. 32. public void remove(){ Integer id = new Integer( facesContext.getExternalContext(). getRequestParametersMap(). get(“id”) ); User user = search(id); if(user != null){ ... } }
  33. 33. SOLUÇÃO?
  34. 34. Pensar mais orientado a objetos e deixar com que os componentes troquem objetos e não “chaves primárias”
  35. 35. <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>
  36. 36. public void setUser(User user){ this.user = user; } public void remove(){ if(user != null){ // ... } }
  37. 37. É fundamental implementar os métodos equals() e hashCode() das entidades da aplicação.
  38. 38. 5º Mau hábito
  39. 39. Usar o valor do submittedValue de um componente como se fosse o valor real do componente.
  40. 40. Apply Restore Process Request View Validations Values Update Render Invoke Model Response Application Values
  41. 41. //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 } }
  42. 42. SOLUÇÃO?
  43. 43. Dividir o formulário em subforms
  44. 44. private Date date; //immediate=false public void calcTaxes(ActionEvent e) { if( date.after ( otherDate ) ) { //calculate } }
  45. 45. A quem recorrer? ✔ Myfaces Tomahawk [t:subform] ✔ Myfaces Trinidad [tr:subform] ✔ JBoss Richfaces [a4j:region]
  46. 46. 4º Mau hábito
  47. 47. Implementam o próprio mecanismo de SEGURANÇA
  48. 48. public class LoginPhaseListener implements PhaseListener { //on RESTORE_VIEW public void afterPhase(PhaseEvent e) { if( !isLoggedIn() && !isLogin() ){ //navigate to login page } } }
  49. 49. SOLUÇÃO?
  50. 50. Utilizem um framework especializado
  51. 51. Usar /faces/* ou *.jsf quando se tem páginas em xhtml pode levar a uma exposição do código fonte.
  52. 52. 3º Mau hábito
  53. 53. Paginação de registros na session
  54. 54. Uma das melhores maneiras de matar a escalabilidade da aplicação é a utilização indiscriminada da session
  55. 55. SOLUÇÃO?
  56. 56. Paginação sob demanda
  57. 57. 2º Mau hábito
  58. 58. Efetuar consultas de maneira INEFICIENTE
  59. 59. <h:dataTable value="#{bean.usersList}" var="user"> <h:column ...> ... </h:column> </h:dataTable>
  60. 60. public class Bean { public List<User> getUsersList() { return service.findAllUsers(); } }
  61. 61. SOLUÇÃO?
  62. 62. Usar consultas em eventos ou callbacks
  63. 63. public class Bean { @PostConstruct public void initialize(){ this.users = service.findAllUsers(); } public List<User> getUsersList() { return this.users; } }
  64. 64. public class Bean { public void search(ActionEvent e){ this.users = service.findUsers( … ); } public List<User> getUsersList() { return this.users; } }
  65. 65. 1º Mau hábito
  66. 66. 1º -e o pior- Mau hábito
  67. 67. JSF LIFECYCLE
  68. 68. JSF LIFECYCLE A maioria dos desenvolvedores NÃO entendem
  69. 69. JSF LIFECYCLE SOLUÇÃO?
  70. 70. http://balusc.blogspot.com /2006/09/debug-jsf-lifecycle.html Entendam o ciclo de vida
  71. 71. Concluindo..
  72. 72. Perguntas?
  73. 73. Obrigado! twitter.com/rponte twitter.com/tarsobessa

×