Arquitetura de uma aplicação JSF

5 respostas
danielbussade

Olá pessoal, sempre trabalhei com Frameworks MVC action-based como Mentawai, VRaptor,etc. Entretanto há uma semana atrás comecei a trabalhar com JSF, achei alguns pontos muito interessantes como os Converters e os Validators,dentre outras coisas mas algumas coisas me incomodaram (talvez seja o modo como estou trabalhando, por isso o post).

No JSF temos os Managed-beans ou Backing-beans, que pelo que li são algo como FormBean do Struts + Bean comum , ou seja nele tenho componente HTML, e as propriedades do meu modelo de negocio algo como:

UsuarioBean 
private String username;
private String password;
private HtmlInputText input; //campo binding
private HtmlOuputText output; //campo binding

Aqui já começa alguns problemas, porque acho estranho misturar componentes HTML com atributos das classes de negócio,
gostaria de saber do pessoal que trabalha com JSF, se essa e a forma usual de trabalhar ou se por exemplo, seria melhor
ter uma classe UsuarioBean, e uma classe Usuario onde UsuarioBean teria por composicao um Usuario assim:

UsuarioBean 
private Usuario usuario;
private HtmlInputText input; //campo binding
private HtmlOuputText output; //campo binding

Neste caso teria sempre duas classes para cada entidade persistivel?

E uma outra coisa que achei diferente, foi o fato de por exemplo, ter metodos de crud nos beans, como no exemplo:

UsuarioBean 
private String username;
private String password;
private HtmlInputText input; //campo binding
private HtmlOuputText output; //campo binding
private UsuarioDao usuarioDao // injetado via IoC

public void save(){
usuarioDao.save(this);
}

public void update(){
usuarioDao.update(this)
}

Aqui não sei também se essa é a forma usual de se fazer, como falei venho de frameworks action-based onde um crud faria desta forma:

REQHTTP-> Action -> Dao -> SGBD

Sendo que a construção da minha classe de negocio já vem populada com os dados da view pelo meu framework MVC, e na minha
action tenho um metodo save onde invoco o Dao e passo como parametro a minha classe de modelo.

Agora desta forma, não tenho action , então poderia considerar um ManagedBean como sendo minha action, numa anologia com um framework action-based, então um save ficaria assim:

REQHttp-> ManagedBean -> Dao -> SGBD

Essa é a forma como vcs trabalham com JSF atualmente , ou existe outro modo de trabalhar?

Obrigado

5 Respostas

tnaires

Olá

Managed beans e backing beans não são a mesma coisa: a diferença é muito sutil. Quando você possui para cada campo da página atributos simples - ligados através da propriedade value - você tem um managed bean. E quando você possui para cada campo da página componentes html - ligados através da propriedade binding - você tem u backing bean. Para um mesmo campo, só há a necessidade de usar um ou outro. Qual usar? Depende. Se você precisar modificar as propriedades dos controles html, use backing beans. Se só os dados são importantes, use managed beans.

danielbussade:
Aqui já começa alguns problemas, porque acho estranho misturar componentes HTML com atributos das classes de negócio,
gostaria de saber do pessoal que trabalha com JSF, se essa e a forma usual de trabalhar ou se por exemplo, seria melhor
ter uma classe UsuarioBean, e uma classe Usuario onde UsuarioBean teria por composicao um Usuario assim: (…)

Você pode manter um bean de negócio no managed bean sim, se ele for um simples DTO. Caso não seja, haverá propriedades que você não deixará visíveis às outras camadas - aí pode não ser interessante.

Você pode colocar os métodos que você julgar necessários no seu managed bean, com o nome que der na telha. Não há nada amarrado como no Struts.

danielbussade:
Aqui não sei também se essa é a forma usual de se fazer, como falei venho de frameworks action-based onde um crud faria desta forma:

REQHTTP-> Action -> Dao -> SGBD

Sendo que a construção da minha classe de negocio já vem populada com os dados da view pelo meu framework MVC, e na minha
action tenho um metodo save onde invoco o Dao e passo como parametro a minha classe de modelo.

Agora desta forma, não tenho action , então poderia considerar um ManagedBean como sendo minha action, numa anologia com um framework action-based, então um save ficaria assim:

REQHttp-> ManagedBean -> Dao -> SGBD


Os dados do managed bean já vêm populados também, é só pegar os valores e passar pra camada posterior. Um managed bean é diferente de uma action, mas nesse contexto que você indicou eles possuem o mesmo papel sim.
Abraços

danielbussade

tnaires:

Managed beans e backing beans não são a mesma coisa: a diferença é muito sutil. Quando você possui para cada campo da página atributos simples - ligados através da propriedade value - você tem um managed bean. E quando você possui para cada campo da página componentes html - ligados através da propriedade binding - você tem u backing bean. Para um mesmo campo, só há a necessidade de usar um ou outro. Qual usar? Depende. Se você precisar modificar as propriedades dos controles html, use backing beans. Se só os dados são importantes, use managed beans.

Porque não posso usar os dois juntos, e se eu quisesse um campo “amarrado”, e ao mesmo tempo quisesse os values do meu Pojo preenchido? Não faria sentido usar os dois?

E se não for um simples DTO( o que na maioria das vezes não é) visto que meus metodos de negocio ficam no model, ou seja todas minhas regras de negócio ficam no model. Model aqui no sentido de classes de negócio.

Como ficaria a arquitetura neste caso? Poderia mesmo assim colocar minhas classes por composição nos maganed beans, ou teria outra forma de fazer?

Não entendi esta parte, porque não ficariam visiveis?

Abraços.

tnaires

Eu falo que não faz sentido porque já tentei fazer isso uma vez, e às vezes o JSF gerava componentes na árvore com ids duplicados. Aí dava erro de renderização. Além disso, se você usar componentes ao invés de atributos simples, você pode pegar o valor que o usuário digitou através do método getValue() do componente. Se você ainda não tiver convencido, há um trecho do CoreJSF que diz o seguinte:

Eu teimei e descobri da pior forma que é ruim manter ambos. Passei horas pra descobrir o motivo do erro.

danielbussade:
E se não for um simples DTO( o que na maioria das vezes não é) visto que meus metodos de negocio ficam no model, ou seja todas minhas regras de negócio ficam no model. Model aqui no sentido de classes de negócio.

Como ficaria a arquitetura neste caso? Poderia mesmo assim colocar minhas classes por composição nos maganed beans, ou teria outra forma de fazer?

Se você por acaso possuir um método getter que seja private ao invés de public, o JSF não vai conseguir invocá-lo quando for passar o valor da página para o bean de negócio. Sacou? Quando tiver esse caso, pode ser melhor criar um atributo pra cada campo.

danielbussade

Entendi, me responde uma coisa. Um managedBean , se encaixa como um COntroller do MVC correto, então neste caso faria parte da camada de apresentação.

Então seria um erro, eu invocar um Dao direto do ManagedBean, pois violaria uma camada chamando direto

Apresentação -> Persistencia

Seria correto passar pela camada de aplicação com algum Façade ou criar um Repository, visto que o repositorio faz parte do negocio, ficando assim:

Apresentação - > Negocio- > Persistencia.

Como faz nestes casos?

Abraços

tnaires

Exatamente.

danielbussade:
Então seria um erro, eu invocar um Dao direto do ManagedBean, pois violaria uma camada chamando direto

Apresentação -> Persistencia

Seria correto passar pela camada de aplicação com algum Façade ou criar um Repository, visto que o repositorio faz parte do negocio, ficando assim:

Apresentação - > Negocio- > Persistencia.

Como faz nestes casos?


Eu não considero errado chamar o DAO diretamente do managed bean, se as seguintes condições forem satisfeitas:

  1. Estamos falando de um CRUD. Aqui, não há nenhuma regra de negócio: tudo o que é preciso fazer é persistir os dados.
  2. Você não tem camada de apresentação. Se tiver, é melhor chamar o DAO a partir dela do que de dentro do managed bean.
    Porém, se você já tem um repositório no seu modelo, use-o. Deixe que o repositório chame o código de infra-estrutura pra você.
Criado 3 de maio de 2009
Ultima resposta 17 de mai. de 2009
Respostas 5
Participantes 2