Os 10 Maus Hábitos dos Desenvolvedores JSF

Os 10 Maus Hábitos dos Desenvolvedores JSF

(Palestra ministrada em diversos eventos desde NOV-2008)

Toda tecnologia tende a trazer consigo um novo paradigma de como desenvolver partes específicas de software, contudo, algumas novas práticas nem sempre são entendidas, e algumas vezes antigas práticas permanecem dentro do novo paradigma tornando-se assim maus hábitos, e com JSF não seria diferente.

Aqui será apresentado 10 discussões sobre os maus hábitos mais comuns entre os desenvolvedores JSF, hábitos encontrados não somente entre iniciantes, mas também entre alguns desenvolvedores mais experientes, e por sua vez será apresentado soluções para cada um deles.

F853760c988228c4a153333407e64f09?s=128

Rafael Ponte

October 22, 2011
Tweet

Transcript

  1. Os 10 (dez) maus hábitos dos desenvolvedores JSF Rafael Ponte

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

  3. BRUNO PEREIRA 19/09/2009 01/01/1990

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

  5. Voltando ao que interessa...

  6. 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”
  7. JSF tenta encapsular toda a complexidade no desenvolvimento web com

    Java
  8. A maioria dos desenvolvedores web que já trabalharam ou trabalham

    com algum framework “action-like” acabam tendo grandes dificuldades ao desenvolverem com JSF.
  9. Criando-se então maus hábitos..

  10. 10º Mau hábito

  11. Usar <c:if/> ou <c:when/> para esconder componentes do usuário

  12. <c:if test=”#{bean.admin}”> <h:dataTable var=”row”> <h:column> ... </h:column> </h:dataTable> </c:if>

  13. Usar <c:if/> ou <c:when/> para esconder componentes do usuário SOLUÇÃO?

  14. Utilizar o atributo rendered dos componentes para escondê-los do usuário

  15. <c:if test=”#{bean.admin}”> <h:dataTable rendered=”#{bean.admin}”> <h:column> ... </h:column> </h:dataTable> </c:if>

  16. 9º Mau hábito

  17. Usar “stateless” EL no atributo rendered em um componente que

    dispare eventos
  18. <h:commandButton value=”Salvar” action=”#{bean.salvar}” rendered=”#{bean.admin}” />

  19. SOLUÇÃO?

  20. Garantir a avaliação consistente da EL entre requisições.

  21. session?

  22. O uso indevido ou exarcebado da session é prejudicial para

    a aplicação.
  23. ✔ Myfaces Tomahawk [t:saveState] ✔ Myfaces Orchestra ✔ Myfaces Trinidad

    [pageFlowScope] ✔ JBoss Seam ✔ JBoss Richfaces [a4j:keepAlive] ✔ etc mais longo que request | mais curto que session
  24. 8º Mau hábito

  25. Usar <redirect/> nas regras de navegação para forçar a mudança

    da URL
  26. SOLUÇÃO?

  27. Simplesmente entendam como funciona um REDIRECT

  28. 7º Mau hábito

  29. Alterar o estado de algum componente no lado cliente [browser]

    através de javascript e esperar que isso seja “entendido” pelo JSF
  30. Firebug

  31. Firebug SOLUÇÃO?

  32. Alterar o estado do componente no lado servidor via AJAX

    e re-renderizar o componente
  33. 6º Mau hábito

  34. Utilização demasiada de parâmetros de request e desenvolvimento voltado a

    "chave primária"
  35. <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>
  36. public void remove(){ Integer id = new Integer( facesContext.getExternalContext(). getRequestParametersMap().

    get(“id”) ); User user = search(id); if(user != null){ ... } }
  37. SOLUÇÃO?

  38. Pensar mais orientado a objetos e deixar com que os

    componentes troquem objetos e não “chaves primárias”
  39. <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>
  40. public void setUser(User user){ this.user = user; } public void

    remove(){ if(user != null){ // ... } }
  41. É fundamental implementar os métodos equals() e hashCode() das entidades

    da aplicação.
  42. 5º Mau hábito

  43. Usar o valor do submittedValue de um componente como se

    fosse o valor real do componente.
  44. None
  45. Restore View Apply Request Values Process Validations Render Response Invoke

    Application Update Model Values
  46. //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 } }
  47. SOLUÇÃO?

  48. Dividir o formulário em subforms

  49. None
  50. private Date date; //immediate=false public void calcTaxes() { if( date.after

    ( otherDate ) ) { //calculate } }
  51. ✔ Myfaces Tomahawk [t:subform] ✔ Myfaces Trinidad [tr:subform] ✔ JBoss

    Richfaces [a4j:region] A quem recorrer?
  52. 4º Mau hábito

  53. Implementam o próprio mecanismo de SEGURANÇA

  54. public class LoginPhaseListener implements PhaseListener { //on RESTORE_VIEW public void

    afterPhase(PhaseEvent e) { if( !isLoggedIn() && !isLogin() ){ //navigate to login page } } }
  55. SOLUÇÃO?

  56. Utilizem um framework especializado

  57. Usar /faces/* ou *.jsf quando se tem páginas em xhtml

    pode levar a uma exposição do código fonte.
  58. 3º Mau hábito

  59. Paginação de registros na session

  60. None
  61. Uma das melhores maneiras de matar a escalabilidade da aplicação

    é a utilização indiscriminada da session
  62. SOLUÇÃO?

  63. Paginação sob demanda

  64. 2º Mau hábito

  65. None
  66. Efetuar consultas de maneira INEFICIENTE

  67. <h:dataTable value="#{bean.usersList}" var="user"> <h:column ...> ... </h:column> </h:dataTable>

  68. public class Bean { public List<User> getUsersList() { return service.findAllUsers();

    } }
  69. SOLUÇÃO?

  70. Usar consultas em eventos ou callbacks

  71. public class Bean { @PostConstruct public void initialize(){ this.users =

    service.findAllUsers(); } public List<User> getUsersList() { return this.users; } } - Callback -
  72. public class Bean { public void search(ActionEvent e){ this.users =

    service.findUsers( … ); } public List<User> getUsersList() { return this.users; } } - Evento -
  73. 1º Mau hábito

  74. 1º -e o pior- Mau hábito

  75. JSF LIFECYCLE

  76. JSF LIFECYCLE A maioria dos desenvolvedores NÃO entendem

  77. JSF LIFECYCLE SOLUÇÃO?

  78. http://balusc.blogspot.com /2006/09/debug-jsf-lifecycle.html Entendam o ciclo de vida

  79. Concluindo..

  80. Perguntas?

  81. Obrigado! Rafael Ponte twitter.com/rponte Tarso Bessa twitter.com/tarsobessa