JAVA SERVER FACES

29/05/2009

Boa Tarde eu estou desenvolvendo uma aplicação Java Server Faces utilizando o Padrão DELEGATE BUSINESS , Mas estou com duvidas como que vou comunicar o Java Server Faces com as camadas de negocios do padrão ,  por exemplo  eu tenho minha classe Dao: e não sei como que vou fazer a comunicação com o  framework , obrigado e fico no aguardo.

package br.com.shift.dao;

import java.util.ArrayList;
import java.util.List;

import br.com.shift.hibernate.HibernateUtil;
import br.com.shift.persistencia.BeanAbstrato;
import br.com.shift.persistencia.Cliente;


public class ClienteDao {

    /**
     * Metodo responsavel por salvar um cliente
     * @param bean
     * @throws Exception
     */
    public void save(BeanAbstrato bean) throws Exception {
        HibernateUtil.save(bean);
    }
   
    /**
     * Metodo responsavel por deletar um cliente
     * @param bean
     * @throws Exception
     */
    public void delete(BeanAbstrato bean) throws Exception {
        HibernateUtil.delete(bean);
    }
   
    /**
     * Metodo responsavel por atualizar um cliente
     * @param bean
     * @throws Exception
     */
    public void update(BeanAbstrato bean) throws Exception {
        HibernateUtil.update(bean);
    }
   
        /**
     * Metodo responsavel por buscar todos clientes
     * @param
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public List<Cliente> findAll(Cliente cliente) throws Exception {
        return HibernateUtil.find(cliente);
    }
   
    /**
     * Metodo responsavel por validar se ja existe um cliente
     * @param nome O nome do cliente
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public boolean buscaNomeCliente(String nome) throws Exception {
        List<Cliente> listaClientes = null;
        StringBuilder query = null;
       
        try {
            listaClientes = new ArrayList<Cliente>();
            query = new StringBuilder();
           
            query.append(" FROM Cliente clientes ");
            query.append(" WHERE upper(clientes.nome) LIKE upper('" + nome + "') ");
           
            listaClientes = HibernateUtil.find(query.toString());
           
            if(!listaClientes.isEmpty())
                return false;
               
        } catch(Exception e) {
            e.printStackTrace();
        }
       
        return true;
    }
   
    /**
     * Metodo responsavel por buscar um determinado cliente
     * @param
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public List<Cliente> buscar(int idCliente) throws Exception {
        List<Cliente> listaClientes = null;
        StringBuilder query = null;
       
        try {
            listaClientes = new ArrayList<Cliente>();
            query = new StringBuilder();
           
            query.append(" FROM Cliente clientes ");
            query.append(" WHERE clientes.id LIKE '" + idCliente + "' ");
           
            listaClientes = HibernateUtil.find(query.toString());
           
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return listaClientes;
    }
}

Cristian Mietlicki

Cristian Mietlicki

Curtidas 0

Respostas

Henrique Weissmann

Henrique Weissmann

29/05/2009

Olá Christian,

bom: com relação ao padrão business delegate (http://java.sun.com/blueprints/corej2eepatterns/Patterns/BusinessDelegate.html), a sua idéia básica consiste em simplificar o acesso aos EJBs de sua aplicação, possibilitando à sua camada de visualização acessar um "intermediário" que, por sua vez, seria o responsável por executar o EJB e retornar o resultado para a camada de visualização. Ele pode ser implementado utilizando o padrão Facade (http://en.wikipedia.org/wiki/Facade_pattern)

No entanto, se a sua aplicação não utiliza EJBs (ou mesmo se utiliza), uma solução mais interessante consiste em utilizar simplesmente o padrão facade. O que deve ser levado em consideração aqui é: o que você deseja isolar da sua camada de visualização? No seu caso, a lógica de negócios, correto? Sendo assim, podemos começar nossa discussão a partir deste padrão.

Utilizamos o padrão facade para a criação de uma interface simplificada a uma lógica de negócio mais complexa. Se você possui por exemplo algum procedimento que seja demasiado complexo, ou seja, que exija a chamada de diversos métodos para atingir algum resultado, ao adotar o padrão facade, você poderia encapsular esta sequencia de operações retornando assim o resultado esperado, ou seja, você estaria criando uma interface simplificada à execução de uma tarefa.

Indo para o seu código fonte, podemos pensar em como implementar um facade de exemplo bem simples: suponhamos que em sua camada de visualização, por alguma razão que só seu cliente pode sonhar, haja a necessidade de listar todos os seus clientes cujo código identificador seja posterior a 100.

Em um dos seus managed beans, você poderia criar uma action tal como a do código abaixo:

public String clientesComidMaiorQue100() {

    ClienteDAO dao = new ClienteDAO();
    List<Cliente> clientes = dao.getAllClientes(); // eu inventei este método
    List<Cliente> resultado = new Vector<Cliente>();
   
    for (Cliente cliente : clientes) {
          if (cliente.getId() > 100) {
                resultado.add(cliente);
          }
    }

  // bla bla bla, final da action, inclusão de variáveis de requisição ou session, etc.
}

Repare o que fiz neste código: eu inclui lógica de negócio na sua camada de visualização, ou seja, comecei a bagunçar a sua aplicação. O facade entra neste problema como uma forma de resolver o problema: no caso, há dois caminhos a serem seguidos:

1. Você pode criar um facade e acessá-lo diretamente. Neste caso, o facade seria chamado pelos seus manged beans. Poderia existir por exemplo um facade como

public class FacadeCliente {

     public List<Cliente> getClientesComIdMaiorQue100() {
           ClienteDAO dao = new ClienteDAO();
            List<Cliente> clientes = dao.getAllClientes(); // eu inventei este método
            List<Cliente> resultado = new Vector<Cliente>();
   
             for (Cliente cliente : clientes) {
                 if (cliente.getId() > 100) {
                         resultado.add(cliente);
                  }

               return resultado;
            }

}

E a action que listamos acima, não acessaria mais a sua classe ClienteDAO, mas sim o facade. A camada de visualização sequer precisaria saber da existência deste DAO. Porém, há um problema: e se você quiser alterar esta lógica de negócio no futuro, ou mesmo manter mais de uma implementação da mesma, aumentando assim a sua flexibilidade no futuro?

(aliás, aqui eu respondi a sua pergunta: não seria o seu managed bean que acessaria os seus DAOs, seria o facade (ou business delegate caso esteja usando ejbs) que o faria. Você está aqui na realidade "passando a bola" para que o intermediário execute esta tarefa para você)

Ai entra a segunda abordagem (que costuma ser a mais recomendada):

2. Você cria uma interface a ser seguida pelos seus facades e os instancia em tempo de execução de acordo com a sua necessidade ou utilizando um motor de injeção de dependências.

Neste caso, a sua action não acessaria diretamente a sua implementação, mas sim uma interface para o Facade, como a exposta abaixo por exemplo:

public interface IFacadeCliente {
          public List<Cliente> getClientesComIdMaiorQue100();
}

Ao trabalhar com JSF você pode pré-configurar os seus managed beans nos arquivos de configuração para definir qual a implementação que melhor se encaixa em determinada situação.

No entanto, nem tudo são flores com o padrão Facade. Conforme o tempo passa, a necessidade de novas regras de negócio vão surgindo. Consequentemente, mais e mais métodos vão sendo incluidos no facade, e este vai ficando mais complexo. Consequentemente, chegará um dia no qual a manutenção desta classe (ou pior ainda, suas diversas implementações caso esteja usando a segunda abordagem) poderá se tornar incrívelmente custosa.

Espero que com esta explicação eu possa ter lhe clareado o modo como são implementados estes padrões. Caso os problemas continuem, estou aqui para esclarecer suas dúvidas no futuro.

Um abraço
GOSTEI 0
Cristian Mietlicki

Cristian Mietlicki

29/05/2009

Henrique o problema é que eu precisaria de uma classe que fizesse o papel da servlet, no caso eu poderia fazer uma action igual no struts ?, você poderia dar um exemplo de como ficaria? Obrigado.
GOSTEI 0
Cristian Mietlicki

Cristian Mietlicki

29/05/2009

Ok , beleza Henrique ja deu certo aqui , pode  fechar o post, obrigado.
GOSTEI 0
POSTAR