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

Transcript

Os 10 (dez) maus hábitos dos

desenvolvedores JSF

Rafael Pontehttp://[email protected]

Tarso Bessahttp://[email protected]

Antes de mais nada, uma provocação gratuita

BRUNO PEREIRA

19/09/200901/01/1990

BRUNO PEREIRA

19/09/200901/01/1990

RIP - REST in Peace

Voltando ao que interessa...

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

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() { 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; }}

- Callback -

public class Bean {

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

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

- Evento -

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 Pontetwitter.com/rponte

Tarso Bessatwitter.com/tarsobessa