Reestruturando uma aplicação Web

Olá pessoal…

Já programo para a Web faz um tempo… mas sou novo no mundo do Java… estou bem empolgado… a tecnologia apresenta diversas soluções para um mesmo problema…
E tenho lido artigos e matérias sobre OO, Patterns, MVC, Camadas e afins…
Com isso surgem diversas dúvidas… e ai vai duas q me assolam neste momento…

Eu e um colega fizemos uma aplicação Web… do jeito q programávamos em ASP… PHP… e outros… conexões em includes… funções pra lá… funções pra cá… regras de negócio, instruções SQL e consultas tudo no JSP…
Então aos poucos estamos remodelando tudo… fizemos uma normalização na base de dados para seguir em frente…

A primeira alteração foi tirar conexão do include JSP e usar o JNDI para mapear os recursos… agora existe uma classe para conexão ao banco onde eu posso utilizar em qualquer lugar…
Então o próximo passo foi tirar o processamento do JSP… criei um Servlet q por enquanto faz a consulta ao banco e atribui os valores aos objetos de negócio… e as instruções SQL também estão no Servlet… por enquanto…

Criei alguns objetos de negócio, como por exemplo o objeto Usuario com seus gets e sets…

public class Usuario {
  private int codigo;
  private String login;
  private String nome;
  private String sobrenome;
  private String email;
  private Grupo grupo;
  private int acessos;
  private Date ultimo_acesso;
    
  public void Usuario(){
  }

  // gets e sets...

}

Vou postar apenas duas dúvidas por enquanto…

Dúvida 1 - A lista


No caso de uma lista de usuários… onde eu tenho q exibir os seguintes dados:

[LOGIN][NOME SOBRENOME][EMAIL][ACESSOS][USUARIO Q LIBEROU O ACESSO]

Notem q o último campo, é um dado que não está na classe Usuario…
Penso q o Servlet deve carregar uma lista e enviar para o JSP que vai exibir a lista…
Detalhe: Estou exibindo esta lista utilizando JSTL… e aos poucos o JSP está ficando sem scriptlets…
Bom… Imagino q essa lista pode ser uma Collection… certo? e na Collection estariam os objetos Usuario com seus atributos populados…
Porém as vezes, é necessário exibir um atributo que não existe no objeto de negócio… no exemplo pe o Usuário que liberou o acesso…
Nesses casos… oq c faz normalmente? Adiciona-se um novo atributo na Classe?
Ou cria se uma outra classe q herda o Usuario e adiciona os atributos que serão usados apenas na lista em questão?

Dúvida 2 - Os DAOs


Quanto aos DAOs… imagino que seja o Servlet que instancia os DAOs, certo?
E o DAO retorna para o Sevlets os objetos de negócio para devolver para o JSP exibir…
No caso da classe Usuario, existe o atributo grupo que é do tipo Grupo… q é uma outra classe… e imagino q deve existir um outro DAO para a classe Grupo…
É certo um DAO chamar outro DAO? Porque se o Servlet chama o DAOUsuario por exemplo… já tem q retornar o usuário com os dados do grupo e tal… neste caso o DAOUsuario chamaria o DAOGrupo?

Tenho mais dúvidas… mas por enquanto vou postar essas apenas…

Valeus…

como assim “Usuario q liberou o acesso”, oq é essa informação?

[quote=“dac”]
Dúvida 2 - Os DAOs


Quanto aos DAOs… imagino que seja o Servlet que instancia os DAOs, certo?
E o DAO retorna para o Sevlets os objetos de negócio para devolver para o JSP exibir…
No caso da classe Usuario, existe o atributo grupo que é do tipo Grupo… q é uma outra classe… e imagino q deve existir um outro DAO para a classe Grupo…
É certo um DAO chamar outro DAO? Porque se o Servlet chama o DAOUsuario por exemplo… já tem q retornar o usuário com os dados do grupo e tal… neste caso o DAOUsuario chamaria o DAOGrupo?

Tenho mais dúvidas… mas por enquanto vou postar essas apenas…

Valeus…[/quote]
Errado, quem usa seus DAOs são suas classes de negócio q recebem esse teu model e fazem algum processamento, o servlet só controla pra onde delegar essas requisições… E com relação a um DAO usar outro, vai ter muita gente dizendo q é ruim q isso e q aquilo e q bla bla bla e é feio, q tem dependencia de mais e o kct, eu pessoalmente acho isso td muito forçado =p

Bom… poderia ser qualquer outro exemplo… mas explico melhor esse:
Imagine que um usuário se cadastra… e esse cadastro fica inativo até que um outro usuário libere o acesso… essa ação fica registrada… e no caso dessa lista, deve ser exibido o nome e o sobrenome do usuário que liberou o acesso…
Minha dúvida é como seria a melhor maneira de enviar essas informações para o JSP exibir…

Legal… por enquanto as regras de negócio ainda estão no servlet… minha idéia é ir separando as camadas de pouco em pouco… sabe como é… acredito ser necessário reestruturar tudo isso mas é necessário mostrar resultados… saca?

Ok… então existe outras formas de fazer… penso q o DAOUsuario é responsável pela interação entre os dados do banco com o objeto Usuario… portanto o DAOGrupo é responsável pelo objeto Grupo… como fazer essas atribuições de valores sem que um DAO use outro?

Valeu!

Cara, legal o que vc está fazendo.
Tenho praticamente o mesmo perfil que você, e estou com a intenção de automatizar alguns processos onde trabalho para que não fique uma coisa manual e permitir`as pessoas que abrem alguns chamados poder realizá-los sem a minha interação.

Tenho uma pergunta ao Matheus, pela especificação(não lembro muito bem)um Servlet só pega as requisições e envia as respostas, não faz nenhum tipo de processamento.

Vamos a pergunta, imagina que tenho meus jsp’s, meu servlet(1 só), minhas classes, etc…Como faço(sem usar qualquer framework) para o servlet saber qual classe deve delegar o processamento?

Entendi. Bem, tu tem alguma relação entre esses 2 tipos de usuários no banco certo? É essa relação q tu tens q passar pra objeto e apresentar. No caso, eu acredito q tu pode perfeitamente colocar um atributo user na classe User q indica quem o liberou.

Um vai usar o outro, acontece q tu pode fazer uso de IoC pra desacoplar essas dependencias, mas te aconselho a não entrar em detalhes nisso agora, esta bom do jeito q esta indo :joia:

O processamento do servlet é saber pra qual command delegar a requisição a ser tratada… e pra saber q pagina delega pra qual classe tu pode chumbar no código mesmo, eu manter um arquivo xml de configuração pra tua app q mapeie isto, q é oq os mais conhecidos frameworks mvc fazem.

A questão é exatamente essa… para todo e qualquer tipo de dado que o Servlet precise enviar para o JSP seria necessário adicionar um novo atributo na Classe? Não existe outro jeito? Bom… vou exemplificar outro caso…

Tenho a lista de usuários… e a para cada linha dessa lista, o fundo vai estar Vermelho para os Inativos e Azul para os Ativos…

Então eu teria q fazer no JSP… um algo do tipo…

<% String sCor = (usuario.ativo ? "#0000ff" : "#ff0000"); %>

Mas aí o processamento fica no JSP certo? Fora o scriptlet…
Ou incluir um novo atributo “cor” na classe Usuario de modo que o Servlet possa enviar as informações bem mastigadas para o JSP… mas esse atributo cor só seria usado nessa lista…

Existem vários casos, principalmente nas listagens onde algumas informações são usadas apenas uma vez…
Pelo que eu vejo… até agora… tenho duas opções:
1 - Adiciono um atributo na classe… onde esse atribuito será usado apenas uma vez…
2 - Processo esses casos no JSP…

É isso mesmo? Não existe uma terceira opção?

Bom… oq eu fiz antes de postar aqui… criei uma classe UsuarioLista que herda o Usuario… e nesse UsuarioLista tem o Usuario que liberou… e a cor do fundo…

Mas não tenho certeza se isso é uma boa prática…

tu tem q ter um atributo boolean isActive no teu User, e no jsp tu ve se é true ou false pra colocar essa cor, tu pode substituir esse teu scriptlet por taglib, ou Expression Language :joia:

Olá,

parabéns pela iniciativa de tentar “aprender do jeito certo” em vez de ir fazendo tudo de qualquer jeito :slight_smile:

  • Classes de domínio NÃO tocam Daos, você pode usar o Pattern Repository, mas isso é outro papo.

  • Esqueça commands, você NÃO vai rpecisar de comands, no máximo de façades

  • Para o problema da lista, por que você não faz sua classe Usuario ter uma associação com o usuario que liberou seu acesso?

  • Definir onde entra o DAOd epende do contexto. No caso eu sugiro a arquitetura:

HTML -> Servlet -> Façade -> Objetos de Domínio
-> DAO

Ou seja: sua Façade usa os DAOs para buscar objetos do SGBD.

Shoes

Esse processo seria o Controller? :ypen:

Shoes… Antes de qualquer coisa… quem seriam esses ?objetos de domínio??

Ok… mas como assim Commands? :y?:

No caso do usuário… sem problemas… eu posso fazer uma associação… mas… algumas vezes precisamos exibir alguns dados que não estão nos objetos de domínio…

Vou dar um exemplo bem melhor pra explicar… e é mais ou menos no q estou trabalhando agora… aí engloba outras dúvidas minhas… vamos lá…

Problema:
Um cliente qualquer liga pro 0800 e reclama e solicita alguma coisa… o atendente registra o atendimento no sistema… esse registro fica pendente com algum outro usuário do sistema… certo? simples…

Bom… estou trabalhando na busca e ba listagem desses registros…

A estrutura:


Não sei se é a melhor forma de demonstrar… mas o diagrama diz que:

1 - O servlet ?Busca? carrega os dados dos campos de <select>, <checkbox>, <radiobox>… enfim… campos pré-definidos do formulário e envia no request para o jsp ?busca.jsp?.
2 ? O jsp ?busca.jsp? monta o formulário HTML;
3 - O usuário clica no submit e envia o POST para o ?lista.jsp?;
4 - O ?lista.jsp? monta um formulário HTML com os campos <hidden> e reenvia o POST para o Servlet ?Lista? em um <iframe>;
5 - O servlet ?Lista? efetua a busca e retorna o resultado para o jsp ?lista_xml.jsp?;
6 - O jsp ?lista_xml.jsp? monta os dados em um XML no seu body… e no seu onLoad() dispara uma função no ?lista.jsp?;
7 - O jsp ?lista.jsp? então carrega o XML do iframe no seu body e transforma usando o XSL lista.xsl

Onde entra minha dúvida? No servlet ?Lista?.. que vai recuperar os resultados da busca…

O processo é:
O Servlet ?Lista? recebe um POST e envia o request/reponse para o ?lista_xml.jsp?

Então a estrutura ficaria assim?

1 - O Servlet instancia o Façade;
Aqui… como eu envio os parametros da busca? Passo o request por parâmetro para o Façade?
2 - O Façade instancia o DAO;
Mesma coisa… passo o request?
3 - O DAO retorna a lista de resultados para o façade;
4 - O Façade retorna a lista para o Servlet;
5 - E o Servlet retorna a lista para o JSP…

É isso?

Semelhante a dúvida da lista, tenho q retornar uma descrição da situação… dizendo quanto tempo o Registro está pendente e com qual usuário…
Por exemplo… “Pendente a 28 dias 5 hs 45 min com Fulano de Tal”…
É um cálculo que faço na data de inclusão e a data atual…
Tem uma outra informação que diz a porcentagem da situação… por exemplo… “40% do tempo total”… que também é um cálculo que faço que depende da prioridade que o registro foi cadastrado… pode ser “1 hora”, “4 horas”, “1 dia”, etc…
Esse tipo de informação é regra de negócio, certo? Teria que estar em uma outra classe? Ou pode ter um método no próprio objeto de negócio… por exemplo… public String getDescricaoSituacao()?

Bom… vou aguardar as respostas… senão não paro de escrever…

Além disso a sexta já está acabando… é hora de me enroscar no velho trânsito estressante de sampa…

Bom final de semana para vocês… amanhã tem mais pra mim…

:okok:

Olá,

Classes de domínio são as que definem os objetos do seu problema. Todo sistema tenta solucionar um problema, essas classes são as diretamente relacionadas á esta solução. Servlets, JSP, DAOs, etc. são relacionadas à tecnologia que voc~e está usando, para cosntruir telas, conextar com SGBDs, etc. O que trabalha no seu problema são as classes de domínio, como Usuario, Chamado, etc.

A sua sugestão de fluxo está bom para o próximo passo.

Command é um Design Pattern muito (mal!) utilizado. Evite seu uso a menso que realmente saiba o que está fazendo.

Não. Servlets são a fronteira entre o mundo HTTP e o mundo dos seus onjetos de domínio. Pegue o que você rpecisa nor equest, transforme num ou mais objetos e passe-os para o Façade. Nunca deixa nada HTTP (Request, Response, Session) passar para seus objetos de domínio (eles devem ser idnependentes disso).

Isso é formatação, na verdade, já que não muda os valores, sóa apresentação destes, você pode fazer uma classe com métodos para formatar os dados, ou usar uma taglib ou algo do tipo.

Shoes

Quanto a nomenclatura das classes…

Qual seria o nome do Façade que retornaria a lista de usuários? Só pra dar uma esclarecida do q ele é responsável…

Pergunto de uma forma melhor…

O Façade é um objeto genérico e tal?

Ou deve-se ter um Façade para cada solicitação?

Apenas o Servlet tem conhecimento da Façade?

Se pronuncia “Façade” mesmo?

Beleza…

Criei um façade para delegar as solicitações para outros objetos…

No caso da busca, criei um objeto com todos atributos possíveis da busca… No Servlet o objeto é atribuído a valores…

Esse objeto é passado para o façade… q por sua vez solicita ao DAO um resultado… q é devolvido como uma Collection… q por sua vez é devolvido para o Servlet… q despacha para o JSP…

Uma dúvida qto ao DAO… oq c costuma fazer para gerar os comandos SQL? Estou pensando em criar uma classe para montar os comandos SQL… q ficariam em um XML…

Gostaria de saber a opnião de vocês…
Seria algo do Tipo…

public class ComandoSQL&#123;
    /**
     * Configura o arquivo xml.... por exemplo... usuario.xml
     * onde estariam as instruções SQL...
     */
    public void setArquivo&#40;String arquivo_xml&#41;;
     
    /**
     * Configura o comando a ser carregado do arquivo XML
     * Por exemplo um... 'seleciona_usuarios'
     */
    public void setComando&#40;String comando&#41;;
	
    /**
     * Configura um parametro... por exemplo
     * setParametro&#40;&quot;@cod_usuario&quot;, &quot;1&quot;&#41;;
     */
    public void setParametro&#40;
        String nome_parametro,
        String valor_parametro
    &#41;;
	
    /**
     * Retorna a instrução montada...
     */
    public String getInstrucao&#40;&#41;
&#125;

E o XML ficaria mais ou menos assim:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot;?&gt; &lt;comandos&gt; &lt;comando nome=&quot;seleciona_usuario&quot;&gt; &lt;parametro&gt;@cod_usuario&lt;/parametro&gt; &lt;instrucao&gt; SELECT NOME, SOBRENOME, EMAIL, ACESSOS, ULTIMO_ACESSO FROM TB_USUARIOS WHERE CODIGO = @cod_usuario &lt;/instrucao&gt; &lt;/comando&gt; &lt;/comandos&gt;

E ai? Muito viagem? :roll:

Já existe algo pronto?

Nesse caso, estude a possibilidade de usar um framework que já faça esse mapeamento pra vc… existem vários prontos :roll:

Você pode utilizar essa técnica:

http://www.guj.com.br/java.tutorial.artigo.115.1.guj

Pergunta 001: o que é um “objeto com todos atributos possíveis da busca”?

Shoes

Por exemplo… tenho lá o formulário html do tipo…

&lt;p&gt; N&amp;uacute;mero&#58; &lt;input name=&quot;txtNumeroIni&quot; type=&quot;text&quot;&gt; a &lt;input name=&quot;txtNumeroFin&quot; type=&quot;text&quot;&gt; &lt;br /&gt; Per&amp;iacute;odo&#58; &lt;input name=&quot;txtDataIni&quot; type=&quot;text&quot; value=&quot;dd/mm/aaaa&quot;&gt; a &lt;input name=&quot;txtDataFin&quot; type=&quot;text&quot;value=&quot;dd/mm/aaaa&quot;&gt; &lt;br /&gt; Solicitante&#58; &lt;select name=&quot;cmbSolicitante&quot;&gt; &lt;option value=&quot;&quot;&gt;Todos&lt;/option&gt; &lt;c&#58;forEach var=&quot;itemTipoSolicitante&quot; items=&quot;$&#123;listaTiposSolicitante&#125;&quot;&gt; &lt;option value=&quot;$&#123;itemTipoSolicitante.codigo&#125;&quot;&gt;$&#123;itemTipoSolicitante.nome&#125;&lt;/option&gt; &lt;/c&#58;forEach&gt; &lt;/select&gt; &lt;br /&gt; Situa&amp;ccedil;&amp;atilde;o&#58; &lt;select name=&quot;cmbSituacao&quot; class=&quot;inputtext&quot; id=&quot;select4&quot;&gt; &lt;option value=&quot;&quot;&gt;Todos&lt;/option&gt; &lt;option value=&quot;*p&quot; selected&gt;Todos Pendentes&lt;/option&gt; &lt;c&#58;forEach var=&quot;itemSituacao&quot; items=&quot;$&#123;listaSituacoes&#125;&quot;&gt; &lt;option value=&quot;$&#123;itemSituacao.codigo&#125;&quot;&gt;$&#123;itemSituacao.nome&#125;&lt;/option&gt; &lt;/c&#58;forEach&gt; &lt;/select&gt; &lt;br /&gt; Aberto por&#58; &lt;select multiple name=&quot;cmbAbertoPor&quot; size=&quot;10&quot;&gt; &lt;c&#58;forEach var=&quot;itemUsuario&quot; items=&quot;$&#123;listaUsuarios&#125;&quot;&gt; &lt;option value=&quot;$&#123;itemUsuario.codigo&#125;&quot;&gt; $&#123;itemUsuario.grupo.nome&#125; - $&#123;itemUsuario.nome&#125; $&#123;itemUsuario.sobrenome&#125; &lt;/option&gt; &lt;/c&#58;forEach&gt; &lt;/select&gt; &lt;/p&gt;

E a classe seria algo do tipo…

[code]public class FiltroBusca {
private long numero_inicial;
private long numero_final;
private Date data_abertura_inicial;
private Date data_abertura_final;
private int codigo_tipo_solicitante;
private int codigo_situacao;
private ArrayList arr_usuarios_abertura;

// gets e sets

}
[/code]

Olá pessoal…

Um tempinho se passou e fiz muitas alterações no sistema. Gostaria d saber a opnião de vcs a respeito…
Está basicamente assim:

1. Filtro
Criei um filtro, onde é verificado o login do usuário e atribui alguns valores no cabeçalho http…

2. Controlador
Um Servlet controlador q despacha a requisição para a classe apropriada… essas classes eu chamei d “lógica”.

3. Classes da Lógica
Essas classes implementam uma interface “LogicaNegocio” onde existe um método “executa(HttpServletRequest, HttpServletResponse)”.
Nestas classes os valores dos formulários são transformados em objetos.

4. Fachada
O nosso velho amigo façade… agora essa classe não faz muita coisa, apenas conhece as classes apropriadas para cada requisição, no caso as classes de regras de negócio… ou seja, tem apenas métodos q utilizam outras classes d um jeito simples… Por exemplo:

public Hashtable getCamposFormularioConsulta&#40;Usuario usuario&#41; throws Exception&#123; Hashtable campos; try&#123; RNDadosFormularios rn_dados_formularios = new RNDadosFormularios&#40;&#41;; campos = rn_dados_formularios.getCamposFormularioConsulta&#40;usuario&#41;; &#125; catch&#40;Exception e&#41;&#123; throw e; &#125; return campos; &#125;

5. Regra de Negócio
Criei algumas classes q chamei d regras de negócio onde as regras são aplicadas… essas classes por exemplo q acessam os DAOs…

6. Dados
As classes DAOs… consultam, inserem, atualizam e excluem os dados…

7. Utilitários
Classes acessadas por diversos objetos. São classes como a classe de conexão com o banco, um gerador de arquivos, um logador, um enviador de correios eletrônicos, etc…

O fluxo é o seguinte:

Filtro > Controlador > Lógica > Fachada > Regras > DAOs

A Lógica recupera as respostas da fachada e dispacha para o JSP…

No tirei todos os scriplets e estou utilizando JSTL…
Para tabelas de listas grandes estou utilizando o recurso do XML + XSLT

Tem alguns outros detalhes, como por exemplo XHTML e poucas tabelas para adequar ao Tableless + CSS…

Basicamente é isso…

Como vcs acham q está?
Tenho uma dúvida qto as camadas… Quem faz parte da camada d apresentação? A fachada faz parte da camada d regras?
No momento estou instanciando todos esses objetos…
Li em algum lugar q as camadas não devem ser instanciadas… mas eu estava sem tempo, deixei para ler depois e perdi o link… isso confere?
Eu precisaria identificar quais classes deveriam ser “static”?

Uma outra dúvida minha… era q eu gostaria d criar um diagrama para apresentar isso…
Com um diagrama de componentes eu conseguiria demonstrar tudo isso?

Valeu galera,
Douglas

Olá,

Muito resumido:

1 - Você está usando um front controller, que tal usar um pronto em vez de fazer o seu? http://mentawai.lohis.com.br

2 - Leia isso: http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html

3 - Como suas regras de negocio acessam os DAOs?

4 - Ta ficando legal, parabens, mas vamos seguindo :wink:

[quote=“pcalcado”]1 - Você está usando um front controller, que tal usar um pronto em vez de fazer o seu?
http://mentawai.lohis.com.br[/quote]

Olá Shoes…
Quais vantagens eu teria em usar esse controller já pronto?

Ok… vou dar uma lida sim…

Utilizando o exemplo da fachada, as regras acessam assim:

public Hashtable getCamposFormularioConsulta&#40;Usuario usuario&#41; throws Exception&#123;
  Hashtable campos = new Hashtable&#40;&#41;;
  try&#123;
    // Recupera a lista de situações &#40;DAO&#41;
    DadosSituacao dados_situacao = new DadosSituacao&#40;&#41;;
    campos.put&#40;&quot;listaSituacoes&quot;, dados_situacao.getLista&#40;&#41;&#41;;
    // Recupera a lista de prioridades &#40;DAO&#41;
    DadosPrioridade dados_prioridade = new DadosPrioridade&#40;&#41;;
    campos.put&#40;&quot;listaPrioridades&quot;, dados_prioridade.getLista&#40;usuario&#41;&#41;;

    // Recupera a lista de colaboradores &#40;RN&#41;
    RNRegistroAtendimento rn_ra = new RNRegistroAtendimento&#40;&#41;;
    campos.put&#40;&quot;listaDestinatarios&quot;, rn_ra.getListaUsuariosDestinatariosLiberados&#40;usuario&#41;&#41;;
  &#125;
  catch&#40;Exception e&#41;&#123;
    throw e;
  &#125;
  return campos;
&#125;

É assim q se deve acessar os DAOs?

Usar algo já testado em centenas de lugares, com muito menos chance de dar erro que uma implementação caseira :wink:

(for aos recursos extras de brinde)

[quote=“dac”]
É assim q se deve acessar os DAOs?[/quote]

Tá difícil dizer sem conhecer seu domínio… essa aplicação fa o que? O que são estes formulários, campos e etc.?