Managed Beans. Não complique, simplifique.

Já é sabido de todos que JSF é um framework web MVC com uma filosofia voltada a component-based. E não diferentemente dos bons frameworks action-based existentes hoje em dia, o JSF também se utiliza de POJOs como parte do controller.

Sim, eu estou falando dos, já muito conhecidos, managed beans. Eles são os responsáveis por intermediar a comunicação entre nossas páginas e o nosso modelo. Até aí tudo bem, não existe qualquer mistério, basta entender um pouco sobre MVC que isso torna-se óbvio.

Se você observar, quando está trabalhando com JSF, notará que cerca de 50-70% do seu esforço é dedicado na implementaçao do managed bean. E que as futuras alterações e correções de bugs estão intimamente ligados a ele. Implementar corretamente um managed bean pode evitar muita dor de cabeça e facilitar na manutenção da aplicação.

Mas você já se perguntou como e qual seria a melhor forma de implementá-los? Não que exista apenas uma única maneira de escreve-los, longe disso, mas em contra partida existem inúmeras maneiras de torna-los realmente ruins.

Escrever um managed bean de forma porca incorreta pode dificultar e muito sua vida e da sua equipe. Falta de legibilidade, dificuldade para escrever testes de unidade e principalmente medo de alterar o código são apenas alguns dos possíveis problemas.

Agora pare e imagine a vida do próximo desenvolvedor que deverá manter tal código. É, não parece algo divertido.

Managed Beans mais responsáveis

A principal responsabilidade de um managed bean é intermediar a comunicação entre as páginas (componentes do JSF) e nosso modelo. Escutar eventos, processa-los e delegar para a camada de negócios são apenas algumas de suas responsabilidades.

Talvez devido a experiência com frameworks action-based muitos desenvolvedores acabam subutilizando os managed beans e sobrecarregando as páginas com lógicas e dados desnecessários. Os managed beans e as páginas usam a abusam do modelo “pull” durante a renderização e (re)construção da árvore de componentes, isto é, basicamente as páginas é quem decidem (através de EL) quais os dados e lógica necessária para que possam ser processadas.

Graças a este modelo nós conseguimos retirar toda lógica de renderização da página e colocando-a onde jamais deveria ter saído, no managed bean. Esta lógica estará localizada nos métodos públicos do managed bean que serão acessados através de EL pela página.

Não importa se a lógica é simples ou complexa, é quase que mandatório que ela esteja localizada no seu managed bean. Então bizarrices lógicas de apresentação nas páginas, que não são difíceis de se encontrar por aí, como esta deveriam ser evitadas:

<h:panelGrid id="pnl" rendered="#{loginBean.usuario.admin == 1 or loginBean.permissao('exibir_painel_de_usuarios')}" />
	...
</h:panelGrid>

Reparem que a lógica de apresentação está, representada através de EL, na página. Se você teve a infelicidade de encontrar códigos assim então há grandes possibilidades de você também encontrar regras de negócio nas páginas, o que é muito pior que encontra-las no controller.

E olha que este foi apenas um exemplo simples e ligeiramente legível, já encontrei códigos mais complicados que este de dificil leitura e horrível de dar manutenção.

O problema disso é se houver a necessidade de mudar a regra (o que muitas vezes ocorre), mas e se ela estiver duplicada por dezenas de páginas, como você faria? Como testa-la? Pense um pouco sobre isso.

Imaginem um código um pouco pior que este (com 3 ou 4 condicionais), mas dentro de um componente de iteração (como h:dataTable ou ui:repeat). É, você nem vai querer imaginar.

A regra de visualização acima deveria está encapsulada no managed bean, a página não deveria conhecer a regra, mas apenas quem a conhece. Então pensando nisso nós poderíamos alterar nosso código para algo melhor, algo como isto:

<h:panelGrid id="pnl" rendered="#{loginBean.permitidoExibirPainelDeUsuariosLogados}" />
	...
</h:panelGrid>

O componente não conhece a regra, mas sabe exatamente a quem perguntar. O código está bem mais legível pois revela sua intenção. Agora está bem mais fácil mudar a regra (pois temos apenas um único ponto de manutenção) e principalmente testa-la através de testes automatizados.

Um managed bean deveria ao máximo tentar esconder a complexidade das páginas através de métodos que revelem a devida intenção, ou seja, a nomenclatura dos métodos é realmente importante e você deveria dar importância a legibilidade do seu código.

Comunicação entre managed beans

O que eu tenho para falar, de longe, se iguala ao que pode ser encontrado no excelente conteúdo sobre comunicação no JSF neste post no blog do BalusC, além de que para mim ele aborda 99% sobre como managed beans podem se comunicar.

O que pretendo falar está mais relacionado em como manter uma conversa (troca de mensagens) saudável entre managed beans. Em como explicitar os parâmetros esperados e como passar parâmetros de um managed bean para outro de maneira coerente.

A comunicacão entre managed beans não difere da troca de mensagens entre componentes de software na orientação a objetos. Cada componente (managed bean) conhece a interface pública do outro componente para que eles possam trocar mensagens.

Sendo, ter esta interface pública bem definida pode facilitar muito a “conversa” entre os managed beans, facilitar os testes, evitar problemas inesperados, diminuir o acoplamento, aumentar a coesão e assegurar contratos e invariantes do componente.

Nada mais claro que um exemplo para assimilar a idéia:

<h:dataTable var="item" value="#{compraBean.itensNoCarrinho}">
    <h:column>
        <h:commandLink value="detalhe" action="#{itemBean.exibirDetalhesDoItem}">
            <f:setPropertyActionListener value="#{item}" target="#{itemBean.itemSelecionado}" />
        </h:commandLink>
    </h:column>
</h:dataTable>

O código acima não tem nada de errado ou anormal, nada do que não estejamos acostumados a ver quase todos os dias. Se repararem há um pequeno “dialogo” entre dois managed beans – compraBean e itemBean – que estão trocando informações.

O problema não está na comunicação em si, pois isso teria que acontecer de um jeito ou de outro, mas sim em como eles se comunicam. O managed bean compraBean conhece detalhes de como o itemBean se comporta, ou seja, ele sabe mais do que o necessário.

Um maneira de melhorar isso seria ter uma interface pública bem definida no itemBean. Algo semelhante ao código abaixo:

<h:dataTable var="item" value="#{compraBean.itensNoCarrinho}">
    <h:column>
        <h:commandLink value="detalhe" action="#{itemBean.exibirDetalhesDoItem(item)}" />
    </h:column>
</h:dataTable>

Além de todos os benefícios (baixo acoplamento, alta coesão etc) citados acima, nós ganharíamos de cara maior legibilidade no código, o que é algo realmente importante quando a comunicação foge do trivial.

Vale ressaltar que independente da comunicação ocorrer na página (por meio da JBoss-EL) ou diretamente dentro do managed bean, essa abordagem poderia -e até deveria- ser utilizada. Para o segundo caso, frameworks como JBoss Seam ou Spring ajudam a injetar as dependências de maneira simples através de anotações.

Um ou vários managed beans?

Não tenho uma opinião realmente formada quanto a isso, ainda não. Já pensei várias vezes sobre o assunto, e sempre me pego vislumbrando cenários nada comuns. Que no caso os considero como casos excepcionais.

Desde 2006 eu trabalho com JSF, ministro cursos e treinamentos e presto consultoria para algumas empresas. E posso dizer que somente três vezes eu precisei ter mais de um managed bean para resolver uma tarefa. Dentre todas eu tenho a ligeira impressão que segui o caminho errado mais complicado, e que se tivesse pensado mais um pouco eu poderia ter evitado tais soluções.

Managed beans são componentes, em sua grande maioria, intimamente ligados a(s) página(s) e que deveriam ter apenas o estritamente necessário para representar a GUI. Dificilmente você terá um managed bean genérico (CRUD não conta) que poderia funcionar em todo lugar. Você precisa fazer um esforço hercúleo para conseguir isso, e as vezes parece que não vale a pena.

A idéia de um managed bean ter dados (entrada pelo usuário e estados) e comportamentos (eventos e regras ligadas a apresentação) juntos segue o princípio básico da OOP, o que torna o trabalho mais simples e coeso. Tentar ir contra isso (ao estilo ActionForm e Action do Struts) pode te trazer muita dor de cabeça a médio-longo prazo.

Neste post do Neil Griffin, um dos autores do primeiro livro de JSF2.0, ele sugere alguns “rótulos” para os diversos tipos de managed beans que podem haver numa aplicação, e ainda por cima ele incita que seria uma boa prática trabalhar com vários managed beans por questões de SoC, baixo acomplamento etc.

De fato, devido ao modelo “pull” podemos ter managed beans atuando como componentes menores, mais reutilizáveis e mais orientados a objetos. Ter componentes (managed beans ou não) de granularidade fina colaborando para construção da página é algo bastante comum, e eu mesmo me utilizo muito disso. Mas não são destes tipos de componentes que falo, muito menos o Neil.

Eu, particularmente, não concordo com quase nada no post do Neil. Para mim ele se utilizou de argumentos isolados e vagos para defender sua idéia. Managed beans por sua natureza deveriam ser simples, contudo a abordagem do Neil, definifitivamente, vai contra tudo isso. Eu a considero um overkill, e ela torna qualquer aplicação web difícil de manter.

Bem, se dois ou mais managed beans relacionados -delimitados a um contexto- estão servindo para você e sua equipe, ótimo. Continue assim, não tem porque mudar. O framework (JSF) te permite isso, contudo eu tenho sérias dúvidas se essa abordagem vale a pena.

Conclusão

Este post estava em draft faz um bocado de tempo, mas a falta de tempo e a coragem não me permitiam finaliza-lo. Felizmente resolvi tira-lo do baú e posta-lo.

Tudo que comentei aqui está mais ligado a minha experiência e o que aprendi durante estes anos como desenvolvedor (e conversando com outros profissionais) do que eu pude encontrar em livros de JSF sobre o assunto. Existem muitos livros bons, assim como artigos em blogs e sites especializados sobre o assunto, mas nada melhor que a experiência do dia a dia para nos mostrar caminhos mais adequados de como solucionar determinados problemas.

Por mais longo que o post tenha ficado, eu ainda sinto que falta complementa-lo em alguns aspectos e pontos. Pois o que falei acima acaba te levando a aderir outras soluções não menos importantes, mas que já foram bastante citadas neste blog e discutidas em listas de discussão.

Entre os três tópicos abordados aqui eu ainda tenho algumas dúvidas quanto ao último, principalmente depois desta resposta do @edburns a minha pergunta no Twitter. Hoje minha opinião está mais para o lado “um managed bean é suficiente” por não ter encontrado respostas que me convencessem do contrário.

Enfim, como disse antes, se vários managed beans intrinsecamente relacionados estão resolvendo teu problema por algum motivo, ótimo! Continue assim. Se você tiver um tempinho e puder comentar sobre tua decisão eu ficaria grato.

53 thoughts on “Managed Beans. Não complique, simplifique.

  1. Apesar de não ter larga experiência com JSF como você, Rafael, eu acho que managed beans devem ser especificos por funcionalidade, por exemplo, pois se você tiver apenas “O MANAGED BEAN”, então alguém terá que ser responsável por fazer esse trabalho de controle.
    Apesar de gostar de trabalhar com algumas soluções genéricas, eu não acho que vale a pena deixar todo o controle por conta de alguém que conhece o que implementou e como será a manutenção disto?
    Lembre-se que as vezes é bom ter um único ponto de implementação, mas nem sempre é obrigatório, pois como você tem um único managed bean, então qualquer alteração deverá ser pensada, para que não resulte em um fracasso em uma outra funcionalidade.
    Essa é a minha opinião e espero ter ajudado.

  2. Muito bom Rafael,
    eu também tinha essa dúvida, após um projeto que participei com o Regis (SERPRO), isso ficou mais claro pelo que o Regis falava. Para mim hoje poucas coisas (ou nenhuma) justifcam o uso de mais de um managed bean por página, um managed bean pertence a uma única página e a página a seu managed bean.

  3. Tenho uma aplicação de BI onde existe uma consulta que se pode fazer vários detalhamentos… basicamente ela vai descendo o nível pra ir especificando a informação. Ex: Consulta de Classificação (tipo um Ranking) da pontuação é detalhada para a consulta de indicadores (pontos pra cada indicador que geraram a pontuação final), depois detalhando para os eventos (cada indicador tem vários eventos que juntos geram a pontuação do indicador) indo por fim aos dados de produção (apenas registros que com uma lógica aplicada, geraram os pontos dos eventos).
    Bom para fazer tudo isso eu uso 4 Managed Beans, sendo 1 pra cada nível de consulta.
    Hoje dentro dos 3 primeiros MBs eu tenho um método que chama o próximo MB da hierarquia, setando os parametros para detalhar.
    Teria uma prática melhor de se fazer isso ?
    Se usasse apenas um facilitaria, pois estaria tudo ali e evitaria ficar chamando outros MBs, mas seria certo ?

  4. Rafael, acha que é válido criar managed-beans mais que o necessário apenas para tentar deixar sua estrutura mais organizada?
    Ótimo post, tente não ficar tanto tempo sem postar hehehe

    Abraços,

  5. Parabéns pelo post!
    Muitas coisas que fazemos acabam sendo feitas por herança de experiências anteriores a capacidade deve haver espaço para auto-crítica, fugindo da mesmice: “Sempre fiz assim e deu certo!” pensar em novas soluções nos leva a evolução.
    esse post me fez refletir muito sobre o assunto…

  6. Pensando de um outro ponto de vista, mas vejam bem, não estou afirmando.

    E se um managed-bean pertencesse apenas a uma determinada entidade (modelo), não seria o mais correto.

    Visto que uma página pode utilizar informações de mais de um managed-bean.

  7. Belo artigo Ponte,

    Eu que estou agora voltando no tempo e trabalhando action-based, entendi bem melhor como trabalhar com MB.

  8. Eu fiquei com uma dúvida, quando voce diz apenas “um” managedbean? Voce quer dizer apenas um por pagina? Ou por aplicação? Ou ainda quem sabe por regra de negocio/funcionalidade??

  9. Ah, se todos que conheço pensassem em seus managedBeans como objetos que realmente possuem estado.

    Vejo os managedBeans muito ‘orientado a funções’ apenas por acessarem diretamente as páginas (visão).

    Leitura obrigatória, esse post.
    Parabéns.

  10. Pessoal, é simples: Para cada arquivo [*.jsf, *.jsp, *.xhtml], devemos ter um – e apenas um – managed bean. O que acontece: cada página tem seu comportamento, e este comportamento é definido por um managed bean. Ele existe para não poluirmos nossa página com EL’s, tags cheias de comportamento. Caso tenhamos que manter estado da tela, quem sabe sobre o estado é a instância do managed bean. É ele o responsável por manter um escopo de conversação. Por isso, cada recurso web deveria estar associado a um único managed bean. Não faz sentido, e fica poluído, termos diversos managed beans associados a um recurso. Em um projeto grande perdemos o controle (e eu já vi isso várias vezes). A definição de como trabalhar com managed beans também depende das necessidades e de outras definições arquiteturais. Particularmente, eu não aceito o uso de ‘scope’ session em managed beans. Isso é algo raro de acontecer. O problema é que o JSF 1 não provê maneira simples de manter estado de managed beans com escopo de requisição no servidor. A solução acaba sendo recorrer a componentes de bibliotecas alternativas: (t:saveState, a4j:keepAlive, …). Porém, ambos se comportam de forma diferente, e a maioria dos desenvolvedores que fazem uso deles, não sabem como realmente funcionam. Vou parar por aqui, mas tem muito mais pontos a se considerar.

  11. Olá Felipe,

    Não há uma regra sobre quantos managed beans devemos implementar para resolver um problema. Como disse no post, hoje em dia eu ainda tenho minhas dúvidas sobre a necessidade de termos mais que um managed bean por tarefa/funcionalidade/UC. Mas ainda não descarto que em certos cenários isso pode fazer sentido.

    Ter um managed bean responsável pela navegação faz sentido quando nos utilizamos de uma abordagem com grande uso de AJAX e baseada em “navegação orientada a estados”. O que é comumente visto em sistema coorporativos (mesmo achando que JSF não seja o ideal fora dessa realidade).

    JSF é um framework literalmente “core”. Ele foi concebido para ser estendido, o seu uso isolado beira a INUTILIDADE. Trabalhar com JSF sem frameworks e componentes auxiliares para estende-lo ou flexibiliza-lo é inviável no mundo real. Eu tenho um post em draft sobre o assunto, em breve, se a coragem e o tempo permitir, eu devo estar postando algo.

  12. Ótimo Rafael,

    Realmente o uso isolado de JSF é inútil. Porém, sua extensão requer cuidados. A empresa onde trabalho hoje foi cobaia de experimentos do querido Urubatan na criação do Spring Annotations, framework já removido de todas aplicações da empresa atualmente. Uma boa configuração com o Spring atual, facelets, e [Richfaces, Tomahawk] atende diversas necessidades. Pro cliente que quiser pagar, temos o renovado ADF. Mas reinventar a roda não vale a pena. Eu, particularmente, acredito que apenas o NavigationHandler exige uma implementação na versão 1 do JSF.

    Aguardo seu post.

  13. Ola Rafael,
    É possível utilizar Entitis do JPA como beans do jsf? ( eu li que não é possível/recomendávelem uma aplicação onde se utilize apenas JSF, Richfaces e JPA (meu caso) por isso nunca tentei, mas, o Jboss Seam permite fazer isso sem problemas, certo? ).
    Agora eu criei uma classe que copia automaticamente os dados dos meus entitis pros Back beans e visse versa. Utilizei para isso a API reflection . Apesar de ter funcionado perfeitamente isso não é recomendável né?

  14. Oscar,

    É possível sim, basta declarar a entidade (ou qualquer classe) como managed bean no faces-config.xml. Eu não vejo problemas nisso, contudo até hoje não tive essa necessidade.

    Eu não entendi seu último paragrafo. Qual a finalidade de criar uma classe para copiar as propriedades de uma entidade para o managed bean? Você poderia simplesmente utilizar a entidade dentro do managed bean.

    Um abraço.

  15. Olá Rafael, estou com um problema ao tentar usar seu método de controle de regras de visualização.

    Usando JSF “puro” ele não reconhece ‘mostrarSeCondicao’ em

    rendered=”#{Bean.mostrarSeCondicao}”

    como um método, mas sim como um atributo. Como você faz para que esse método seja executado corretamente? Usa alguma ferramenta adicional ao seu JSF?

    Abraço!

  16. O lá Rafael,
    Tenho uma classe cliente que tem um relacionamento com a classe telefone e um cliente pode ter vários telefones, ou seja, uma lista de telefones.
    Não estou conseguindo passar esses telefone da view para o controller. Como devo receber estes dados na view? E como faço para o controller receber esses dados e salvar no banco.
    Estou usando hibernate.

  17. Como vai Rafael?

    Estou com um problemão aqui. (segue código)

    na página com a pesquisa

    no método do Bean
    public String produtoViewLink(Produto produtoAux){
    this.produto = produtoAux;
    return “produtoView”;
    }

    na view de retorno
    #{produtoBB.produto.nome}

    caso eu remova a action do h:commandLink action=”produtoBB.produtoViewLink(item)”, funciona perfeitamente.

    E segue o erro:
    SEVERE: Erro…javax.servlet.ServletException: /pesquisa.xhtml @73,126 action=”#{produtoBB.produtoViewLink(item)}” Error Parsing: #{produtoBB.produtoViewLink(item)}
    e LOG
    SEVERE: Servlet.service() for servlet Faces Servlet threw exception
    org.apache.el.parser.ParseException: Encountered ” “(” “( “” at line 1, column 28.
    Was expecting one of:
    “}” …
    “.” …
    “[” …

    Ele chora alguma coisa na EL, qual devo usar?

    Não queria ter que recorrer ao uso de biding com escopo de session. Sei que é feio, errado, no entanto é que venho fazendo. Espero que por enquanto.

    Outra dúvida: é possível usar biding nos dataTable e recuperar o valor da linha clicada usando beans com escopo de request?

    Rafael, Só você para estas questões, Obrigado!

  18. No entanto, infelizmente como Corinthiano e agora tentando ser programador, sei bem disso. Tanho outro:

    A action não é executada dentro da dataTable (segue código sem a notação , para que possa aparecer no post

    View
    h:dataTable value=”#{pesquisaBB.produtos}” var=”item” id=”pesquisaDataTable” styleClass=”ui-datatable” headerClass=”textAlignLeft”
    h:column
    h:form id=”itemView2″
    h:commandLink value=”#{item.nome}” action=”#{produtoBB.produtoViewLink(item)}”/
    /h:form
    /h:column
    /h:dataTable

    Bean
    public String produtoViewLink(Produto produtoAux){
    System.out.println(“Passei por aqui!”);
    this.produto = produtoAux;
    return “produtoView”;
    }

    Coloquei inclusive um System para testar e nada, inclusive elevei o contexto dos Beans para session e nada. O Server nada executa.

  19. Olá Fabiano,

    Como você mesmo já descobriu como resolver o seu primeiro problema (existe uma link de referência também nesse post, rss), então vou pular sua dúvida, ok?

    Segunda dúvida: sim, você pode recuperar o valor da linha clicada mesmo o seu managed bean estando em request. 1) Uma maneira simples é utilizando algum componente que estenda o escopo conversacional, um escopo maior que request e menor que session, como t:saveState do Tomahawk ou a4j:keepAlive do Richfaces. 2) A maneira complicadinha é garantir que sempre que a dataTable avaliar a EL que representa a lista de objetos o managed bean retorne a mesma lista (mesmo que tenha que ir buscar de novo no banco).

    Este post do BalusC tem algumas dicas,
    http://balusc.blogspot.com/2006/06/using-datatables.html

    Espero que tenha te ajudado.

    Um abraço.

  20. Boa noite Rafael.

    Estou com um problema, espero que vc possa me ajudar. Tenho duas páginas JSF, um para listar os clientes outro para edita-los também tenho três managed bean dois deles com o escopo request e um com o esposo session, uso os de request receber dados e passar para o de session e ele deve acessar os métodos do meu sessionBean porém quando tento acessar não consigo pegar a seção. Será que pode me ajudar ?

    Desde já obrigado.

  21. “Existem muitos livros bons, assim como artigos em blogs e sites especializados sobre o assunto, mas nada melhor que a experiência do dia a dia para nos mostrar caminhos mais adequados de como solucionar determinados problemas” – Disse tudo e mais um pouco…

  22. Para otimizar e alavancar o uso de conceito JSF-2, utilize-o SEMPRE em conjunto com o JBoss-Seam!!!! Ele resolve problemas de Beans mantidos, transação, etc…. Integra de forma eficaz e graciosa toda arquitetura q elvouve JSF, com alta curva de produtividade.

  23. Bom galera, minha duvida é a seguinte, estou precisando passar valores entre beans. Por exemplo, o usuário faz login no sistema, um atribuito grava o usuário logado, com isso em outros beans preciso saber o usuário que está logado no sistema. Como faço isso no JSF 2.0 ? Grato pela ajuda.

  24. Bom dia Rafael, e nos casos onde se usa LoV? tenho uma aplicação de uma imobiliaria onde na tela de imovéis usamos e abusamos desse padrão,nesta tela por exemplo temos a modal de consulta de empreendimentos ,nesta modal temos os filtros e a lista de empreendimentos onde ao selecionar o empreendimento setamos o empreendimento do imóvel.para isso eu tou usando 2 managed beans ,o imovelBean que trata da entidade imóvel e o empreendimentorBean que trata da entidade empreendimento.No momento da seleção do empreendimento temos
    seria correto isso arquiteturalmente falando? Na verdade estava pensando até em criar mais um managedBean só para a consulta do empreendimento pois eu já uso o empreendimentoBean para o crud de empreendimento,ai eu usaria este pesquisaEmpreendimentoBean para a listagem de empreendimentos na pagina list-empreendimento.xhtml na crud quanto para as modals de seleção,mas tenho a impresão que vai ficar muito granularizado/espalhado não sei se é a melhor escolha,nem se é correto eu fazer isso .Qual sua opinião a respeito? 1 managed bean por lógica?página?caso de uso? vários managed beans neste cenário acima vc acha válido?

  25. Seria interessante tbm usar um managedBean auxiliar para carregar as combos da aplicação como feito em http://www.rponte.com.br/2008/02/24/aproveitando-os-beans-do-spring-em-suas-paginas-jsf/ ?Atualmente estou carregando os itens das selects no próprio managed bean por exemplo na mesma página de imovel eu tenho varias selects como por exemplo tipoImoveis eu tou carregando essas combos tanto no bean imovelBean quanto no bean pesquivaAvancadaImovelBean sinto que poderia criar um bean só para carregar as combos ou então carregar essa lista no bean tipoImovelBean,mas novamente não sei qual seria a melhor abordagem, tive um outro problema tbm que esse sim eu me vi obrigado a utilizar um outro managed bean: o componente p:graphicalImage não funciona com @ViewScope então tive que criar um outro managed bean apenas para exibir uma imagem oriunda do banco de dados.Bom queria saber a opinião de vcs , comoa galera tá implementando estes tipos de situações.Desde já agradeço.

  26. Oi Ricardo,

    Foram várias perguntas em um contexto maior que acredito que eu não entendi bem. Vamos ver se consigo te ajudar em algo.

    No geral, não existe uma regra que diga quantos managed beans você deva utilizar em suas telas. Na maioria dos casos um único managed bean é suficiente, em alguns poucos casos o uso de 2 ou mais managed beans podem facilitar e muito a vida, seja por questão de reaproveitamento de features/código ou deficiências da própria especificação.

    No caso do lov, se o lov for reaproveitável em outras telas, acredito que vaila a pena sim tê-lo isolado num managed bean.

    Se puder, entra no grupo de discussão da #javasf, lá poderemos prolongar essa discussão e ter a opinião de outros membros que utilizam 1 ou mais managed beans em suas aplicações.

  27. Olá Rafael,

    Li todo o seu artigo, parabéns, continue nos trazendo esse conhecimento crítico e que nos faz pensar melhor ao trabalhar com isso.

    Estou montando minha infra web. Já finalizei toda a parte de business, que no caso utilizei spring e hibernate. Para fazer o aproveitamento de código, criei serviços genéricos com os crud’s básicos. A minha dificuldade é qual pode ser a melhor forma de eu trabalhar em meu MB fazendo proveito desses serviços.

    Minha página na web é simples, contém um dataTable e um Dialog. O dialog será para inserir e editar as informações.

    Tenho como serviços:
    – getAll
    – CRUD básico.

    Abraços

  28. Oi Augusto,

    Não existe uma resposta fácil para sua pergunta. Existem diversas maneiras de implementar um CRUD e isso normalmente difere de projeto para projeto e framework MVC.

    O ideal é descobrir o padrão do seu crud e construir suas classes genéricas em cima disso, ou seja, a necessidade da tua tela (crud) te guiará no melhor design das tuas classes. Se tuas telas forem baseadas em muito ajax então vá em frente, se for navegação convencional também não terá problema.

    Não existe o certo ou errado, depende sempre do contexto do projeto!

    Se eu puder te ajudar em mais alguma coisa, por favor, é só falar.

    Um abraço.

  29. acho também que um MB da conta do recado, caso o dev precise criar mais de um é pq tem coisa errada.

    agora um MB genérico pode existir sim em alguns contextos, aqui mesmo temos MB genérico com escopo de session.

  30. Ótimo post!! Rafael, no seu exemplo de troca de mensagens entre managedBeans, eu até consigo recuperar o parametro setado atraves da tag f:setPropertyActionListener, mas ao redirecionar para outra pagina o valor do atributo se perde. Como resolvo isso sem usar escopo de sessão ou conversação?

  31. Olá Cristiane,

    Obrigado!

    O problema é depois que você recupera o valor no outro managed bean? Você está fazendo utilizando a navegação do faces com REDIRECT, seria isso?

  32. Rafael, parabéns muito bom o seu post! sei que é um pouco antigo mas eu estou sofrendo um problema agora referente a isso. Podemos dizer que não é um problema de sistema pois o managedBean funciona muito bem, o problema é que o mesmo possui 5000 linhas, e para dar manutenção nisso como é que faz??

    Acredito que poderia ser divido em alguns managedBeans as ações da tela.

    att
    Herbert Martins.

  33. Oi Herbert,

    Dividindo para conquistar seria uma solução para este problema. Ter 2 ou mais managed beans poderia ser uma alternativa (ou, colocando regras de negócio nos componentes certos, como Services, Daos etc).

    Quebrando a funcionalidade principal em funcionalidades menores você poderia ter managed beans com responsabilidades bem definidas.

  34. Olá Rafael, em um sistema estou utilizando 3 managed beans para cada caso de uso, só contextualizando por exemplo tenho o caso de uso manter contrato,tenho a página de pesquisa e a página de alteração,trafego entre as páginas com include dinâmico via ajax e através do mesmo managed bean ContratoMB que mantenho em ViewSope, acontece que nesse cadastro eu posso fazer upload dos documentos,fazer download de documentos ou exibir os documentos através do p:media, como os outros casos de uso também vão ter essas funcionalidades de upload,download e exibição eu optei por colocar essas responsabilidades em managed beans separados,assim posso reaproveita-los nos outro managed beans e não espalho código, e também pela questão do problema do meu bean principal ser viewscope e o p:media por exemplo só trabalha com session ou application, será que esse é um dos possiveis casos em que separar uma atividade em vários managed beans vale a pena?

    Outra questão,em cadastros do tipo mestre-detalhe, uma relação do tipo:(pedido possui itens), você trata o todo e os agregados em um unico managedBean ou cria um para a entidade pai e outra para a entidade filha?

    • Oi Ricardo,

      Eu diria que sim, é um bom motivo para separar em 2 ou mais managed beans. Principalmente por causa da limitação do p:media e pelo reaproveitamente de código. É sempre bom aproveita o IoC/DI do CDI, Spring ou mesmo do Jsf.

      Sobre mestre-detalhe, normalmente eu trabalho com apenas um único managed bean. Se o cadastro for muito complexo, cheio de detalhes, validações e eventos então eu poderia separar em 2 managed beans. Mas como sempre, só analisando o caso de perto.

      No fim, se você perceber que terá um código mais simples de manter ou enxuto, então separe em quantos managed beans você achar necessário.

      • Eu fiquei pensando a respeito, entendo que os Managed Beans são fonte de dados / ações para as views. Ambos os cenários atendem. Porém pensando em OO, menor granularidade favorece a reutilização em outras páginas. Também ocorre invariavelmente mudança nas próprias páginas XHTML. Caso mudem, logo o meu Managed Bean mudará na mesma proporção para acompanhar a tela, se for feito apenas para aquela tela. Se eu fizer pensando em funcionalidade pode até ser que mude algo ou nada do lado do Managed Bean, pois a tela apenas usa aquela(s) funcionalidades(s). O que você acha?

        • Oi Dênis,

          Se eu entendi bem o que você disse, você está dizendo que apesar dos managed beans terem sido concebidos para satisfazerem as páginas, eles ainda podem ser implementados de forma independente e reutilizável, ou seja, seguindo os princípios OO. Se for isso então eu concordo com você!

          Só lembraria que, para estes casos, o managed bean criado deve ser pensado já com reutilização em mente. Dessa forma, diminuímos o acoplamento com as telas.

  35. Primeiro, parabén pelo excelente conteúdo do post. Eu já utilizei mais de um MB para uma página no caso em que eu tinha uma entidade Pessoa e outras entidades que herdavam de pessoa, como hóspede, funcionário, visitante, etc. Nesses casos, precisei de funcionalidades que eram comuns a todos e então coloquei os métodos em um MB de Pessoa.

    Abraço!

Leave a Reply

Your email address will not be published. Required fields are marked *