Padrões de projeto, deem-me suas opiniões

32 respostas
juninhodg

Bom dia pessoal. Estou desenvolvendo um projeto concreto em Java utilizando eclipse e fico muito confuso por ser iniciante sobre os tais padrões de projeto. Já ouvi falar do DAO que serve para manipulação dos dados do objeto, do MVC, que separa as camadas de modelos de objeto, visualização, e controle, contudo, não sei organizar meu projeto direito ainda. Eu já tenho conhecimento de OO, o próximo passo mais importante seria aprender melhor essas técnicas ou tem outra coisa que eu tenha que entender para me firmar mais na programação em Java?

Abraços.

32 Respostas

nel

juninhodg:
Bom dia pessoal. Estou desenvolvendo um projeto concreto em Java utilizando eclipse e fico muito confuso por ser iniciante sobre os tais padrões de projeto. Já ouvi falar do DAO que serve para manipulação dos dados do objeto, do MVC, que separa as camadas de modelos de objeto, visualização, e controle, contudo, não sei organizar meu projeto direito ainda. Eu já tenho conhecimento de OO, o próximo passo mais importante seria aprender melhor essas técnicas ou tem outra coisa que eu tenha que entender para me firmar mais na programação em Java?

Abraços.

Conhecendo a sintaxe do Java e experiência com desenvolvimento OO, já tem um ponto positivo e importante.
Aprender, sempre temos. Você exerce a profissão a anos e sempre precisa manter-se atualizado, isso é inevitável. Sobre o que aprender, vai um pouco do nicho que você deseja atuar. Tentar aprender JEE e AWT ao mesmo tempo, pode ser um problema, por exemplo.

Sobre os padrões de projetos, são inúmeros. Mas eu diria que ter em mente MVC (senão me engano, tem um conceito mais atualizado), OO e “desenvolvimento orientado a interfaces” é fundamental para iniciar qualquer projeto. Você já tem uma área de atuação que deseja seguir ?

juninhodg

fala nel. Cara eu já atuo como programador Delphi - Firebird - MySQL em sistemas de automação comercial e soluções para empresas como controle de frotas de veículos. Só que eu ando visando há algum tempo “migrar” pra Java, pela flexibilidade da linguagem ser incomparavelmente maior. Não pretendo sair dessa área por enquanto, e se for sair, me aprofundar bastante nos conceitos mais importantes antes de fazê-lo.

nel

Não é a isso que eu me refiro.
Você tem interesse em Java e quer seguir a área, ok. Comece pelo básico, procure apostilas (Caelum tem ótimas apostilas) para estudar o básico, ver bem OO, as classes “básicas”, como Collection, Maps, Wrappers que são usadas no “dia a dia”. Feito isso, podes definir uma área de atuação.

Quando me refiro a área de atuação, digo, Mobile, Desktop, Web…

juninhodg

ah to ligado. Já passei por essas apostilas. Você quer dizer a plataforma que eu quero seguir. Eu estava pensando inicialmente em desktop, depois poderia me aprimorar pra web, já que programar em Java pra web é um trabalho bastante chato. Tenho receio de não acompanhar direito as coisas hehe

nel

Porque “bastante chato” ? Qual sua experiência com Java Web ?
Enfim, seguir uma área que tu acha “chata”, já não é um bom caminho. Se gosta de sistemas Desktop, vai fundo. É só dedicar estudos a este tipo de nicho.
Isso inclui as pesquisas sobre padrões de projetos com Desktop :slight_smile:

juninhodg

nel, aqui no Nordeste falar que uma coisa é “chata” as vezes (que é o caso) significa dizer que é uma coisa complicada hehe. Eu vi bastante de uma apostila de Java Web da Caelum que inclusive abordava o framework Spring e cheguei bem a frente dela. É de fato muito promissor, mas eu gostaria de me aprimorar nesses padrões de projeto para não ter dores de cabeça quando precisar dar manutenção em um sistema. Sou muito exigente em fazer um código limpo e bem estruturado desde que comecei a programar, daí vem esse interesse nos padrões de projeto Java :slight_smile:

nel

Isso é correto. Mas o Spring é apenas um dos frameworks possíveis de serem usados em JEE. Tem um leque de opções bem significativo.
O que eu quis dizer, é que existem padrões de projetos específicos para cada área. Dê uma olhada: http://www.corej2eepatterns.com/

ServiceLocator, isso existe em Mobile? Faço a menor ideia.
Por isso estou dizendo, direcione os estudos a uma área e procure atuar nela.
Ser difícil pode ser uma vantagem, diminui a concorrência e pessoas que conhecem sobre a mesma :slight_smile:

x111

Cara, primeiro eu recomendo.

  1. Use a cabeça Padrões de Projeto
  2. TDD Desenvolvimento Guiado por Testes
  3. Padrões de Arquitetura de Aplicações Corporativas
  4. Domain Driven Design
  5. Padrões de Projeto - Soluções Reutilizaveis de Software Orientado a Objetos

Por incrível que pareça, o grande problema que eu vejo é você já ser experiente! Como você vem do delphi OO não é uma coisa muito natural e você tenderá a criar programas extremamentes procedurais, separando a logica de dados criando os famigerados BOs, TOs e usando DAO.

Esses livros vão te dar um bom feedback das melhores práticas. O primeiro é só uma introdução aos padrões de projeto mais básicos. O segundo contém os padrões mais comuns em aplicações corporativas e é um livro que todo o programador que trabalha com isso deveria ler. O terceiro livro é um que todo o programador deveria ler, ele ensina a como criar um dominio rico, ou seja modelar um sistema que represente fielmente a atividade para qual foi desenvolvido.

Como conselhos eu diria:

  1. Nunca começe modelando pelo banco de dados! Comece organizando as suas classes, depois faça o mapemento delas para o banco de dados.
  2. Não utilize DAO, BOs e TO. Crie um modelo de dominio e utilize um repositório.
  3. Crie sempre testes, ou melhor utilize TDD efetivamente.
  4. Tente separar bem as camadas e não criar acoplamento (Se você utilizar TDD seu acoplamento entre classes será baixo, mas poderá haver acontecer entre as camadas).

Qualquer duvida, estamos ai!

juninhodg

Vou dar uma olhada nesse livro aí que você mandou cara. Me responde uma coisa, vc que é JWizard: Existe muito trabalho pra migrar uma aplicação de Java SE para Java EE em termos de regras de negócio? Digamos que eu tenha um sistema de controle de o que quer que seja, eu vou ter muito trabalho pra fazer esse mesmo sistema, com as mesmas funcionalidades pra Web e Desktop por exemplo?

juninhodg

x@ndy, o pessoal fala muito bem dessa série use a cabeça, vou me acalmar e começar por ele mesmo pra depois seguir a sua orientação. Delphi é realmente muito procedural e apenas ver o quão bagunçado o código ficava, mesmo você tentando organiza-lo, isso me deixava doente. Deve ser TOC rsrs. Muito agradecido pelas dicas. Abraço.

x111

Isso depende, se você separou bem as camadas, se usou MVC por exemplo, é tranquilo pois as regras de negócio estão todos na camada de dominio, então tanto faz você ter uma interface web ou desktop agora se você fez “Interface Inteligente” ou seja, as regras de negocio está junto com os formulários (como é feito muito no delphi) você terá um problemão.

Um jeito simples de saber se suas camadas estão acopladas é o que Martin Fowler fala no livro Padrões de Arquitetura de Aplicações corporativas:

Martin Fowler:

Uma das partes mais difíceis de trabalhar com lógica de domínio parece ser que as pessoas frequentemente acham difícil reconhecer o que é lógica de domínio e o que são outras formas de lógica. Um teste informal que gosto de aplicar é imaginar a adição de uma camada radicalmente diferente a uma aplicação, como uma interface em linha de comando a uma aplicação Web. Se, para fazer isso, você tiver que duplicar alguma funcionalidade, é um sinal de que a lógica de domínio vazou para a apresentação. De maneira semelhante, você tem que duplicar lógica para substituir um banco de dados relacional por um arquivo XML?

nel

Provavelmente, sim.
É claro que depende de algumas variáveis, mas eu diria que são coisas completamente diferentes, por mais que tu separe adequadamente as camadas.

Existem padrões que são extremamente aconselháveis a serem usados em Web, cujo padrões não podem ser utilizados em sistemas desktop.
Se falarmos em aplicações de grande porte, estamos falando em usar servidores de aplicação e não apenas um container Web.
Dessa forma, temos que buscar entender o máximo possível a especificação JEE, para que possamos segui-la e evitar maiores dores de cabeça.

Trabalhava com Glassfish quando foi decidido migrar para o JBoss 7.1.1. Tivemos alguns retrabalhos, pois cada AS tem suas peculiaridades, mas basicamente não foi em código e sim em configurações e isso porque procuramos seguir o máximo a especificação.

Então, tenha cuidado ao comparar desenvolvimentos que seguem linhas de raciocínio distintos. Obviamente, como o próprio x@ndy citou, quanto mais desacoplado seu código estiver, menor será o retrabalho. Por isso seguir boas práticas no desenvolvimento é essencial, independente para qual área deseja atuar.

Só para finalizar, a nível de apresentação, tu terá preocupações com eventos AWT entre outros, em relação a Web, você precisa definir o que vai usar e posso te falar colega, tem zilhões de opções.

ViniGodoy

Só um detalhe: O Delphi é uma linguagem orientada a objetos, e não procedural.

E OO é bem natural. Há muitos exemplos de padrões e boas práticas na VCL (que inclusive inspiraram boa parte da API do java).

x111

ViniGodoy:
Só um detalhe: O Delphi é uma linguagem orientada a objetos, e não procedural.

E OO é bem natural. Há muitos exemplos de padrões e boas práticas na VCL (que inclusive inspiraram boa parte da API do java).


Ele não quer dizer que Delphi não seja OO e sim que criar programas em Delphi com UI gera programas bem procedurais.

E Viny, desculpa, mas OO não é nada natural para quem programava de maneira procedural. Digo isso pq levei um boomm tempo até realmente aplicar de maneira efetiva o paradigma!

Quando se começa a usar OO de quem veio do paradigma procedural é separar a lógica dos dados e gerar os famigerados BOs e TOs. Isso é uma praga que assola os sistemas não somente devido ao EJB 2, mas por que é extremamente natural para quem programava de maneira procedural.

Existe também o problema do acoplamento entre objetos! Acoplamento é algo que parece natural em procedural devido a dependência de bibliotecas, mas objetos não são bibliotecas!

E não podemos esquecer do coesão, embora também seja um problema no mundo procedural, possui um impacto maior ainda no paradigma OO.

A VCL realmente é fantástica, mas não considero Delphi a melhor linguagem para OO, principalmente pela falta de um gerenciamento de memórias efetivo e de intefaces indepententes do SO. Para se ter um sistema realmente OO isso é necessário implementar a contagem de referência (o João Morais, grande especialista sobre delphi, fala sobre isso [urlhttp://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html]aqui[/url]) na mão o que um porre e pode deixar cheio de memory leaks. Fora outros problemas como ele permitir que classes com métodos abstratos sejam instanciadas e não ser possível tornar o construtor privado!

ViniGodoy

Mas quem são as pessoas que programam de maneira procedural que você está falando? O Delphi não é uma linguagem procedural. Ele é orientado a objetos. Tem classes, interface, polimorfismo… A própria VCL implementa padrões de projetos como o observer, chain of responsability, mediator… Ou você se refere a programadores que vieram do Pascal (que não parece ser o caso do colega)?

Digo porque fui programador Delphi por anos. E usavamos OO normalmente. Aliás, meu primeiro contato com padrões de projetos ocorreram justamente por recomendação do manual da VCL. E foi o Delphi a linguagem que me fez migrar do paradigma estruturado para o OO. Foi nele que aprendi a usar polimorfismo, e que entendi para que serviam interfaces.

O artigo que você postou não fala nada sobre a necessidade de contagem de referências para se implementar um modelo realmente OO. Ele só mostra uma forma de implementar o mecanismo em Delphi. Gostaria de ver uma referência que relacionasse uma coisa a outra. No C++, por exemplo, existe OO sem contagem de referências.

Não vou negar que contar referências ou garbage collection simplificam muito o projeto (e daí, o artigo que vc postou e os smart pointers do C++) e que, de maneira geral, seja extremamente vantajoso ter contagem de referências. Mas contagem de referência nunca foi um requisito para um sistema ser orientado a objetos, e sistemas de performance crítica ou requisitos mais agressivos de memória frequentemente optam por não usa-la, mesmo pagando o custo da complexidade e risco de um memory leak.

Agora, programar estruturado em Delphi, é como programar estruturado em Java. Você pode criar um sistema em Java onde tudo esteja implementado na view, seja numa tela Swing ou num JSP, e praticamente deixar toda lógica dentro de event listeners. Isso é uma má prática em Java, assim como é em Delphi.

ViniGodoy

Ok… fazendo um mea culpa. Acho que sei de que programadores você está falando: boa parte dos programadores Delphi do Brasil não programam bem. Ou mantém sistemas legados mal escritos, de maneira procedural.

Infelizmente, a linguagem leva a culpa.

O Delphi não foi construído com MVC em mente. Mas MVC não é o único paradigma que se pode aplicar ao construir interfaces gráficas (o que não significa que outros sejam melhores). E creio que a linguagem acabou optando pelo paradigma errado (usar mediação através de componentes, e abusar bastante dos data bindings).

Mas é bom não confundir as coisas. MVC não é requisito para um sistema “verdadeiramente OO”. Existem outros tipos de arquiteturas, como a arquitetura de componentes (fortemente baseada em composição), que tem dado resultados tão bons ou até melhores do que o MVC.

De qualquer forma, é sim possível (e relativamente fácil) fazer um sistema bem dividido em camadas em Delphi. Entretanto, acho que o colega faz bem de sair da linguagem, afinal, ela já não é mais expressiva para o mercado, ou para a sua carreira.

V

x@ndy:
Cara, primeiro eu recomendo.

  1. Use a cabeça Padrões de Projeto
  2. TDD Desenvolvimento Guiado por Testes
  3. Padrões de Arquitetura de Aplicações Corporativas
  4. Domain Driven Design
  5. Padrões de Projeto - Soluções Reutilizaveis de Software Orientado a Objetos

Por incrível que pareça, o grande problema que eu vejo é você já ser experiente! Como você vem do delphi OO não é uma coisa muito natural e você tenderá a criar programas extremamentes procedurais, separando a logica de dados criando os famigerados BOs, TOs e usando DAO.

Esses livros vão te dar um bom feedback das melhores práticas. O primeiro é só uma introdução aos padrões de projeto mais básicos. O segundo contém os padrões mais comuns em aplicações corporativas e é um livro que todo o programador que trabalha com isso deveria ler. O terceiro livro é um que todo o programador deveria ler, ele ensina a como criar um dominio rico, ou seja modelar um sistema que represente fielmente a atividade para qual foi desenvolvido.

Como conselhos eu diria:

  1. Nunca começe modelando pelo banco de dados! Comece organizando as suas classes, depois faça o mapemento delas para o banco de dados.
  2. Não utilize DAO, BOs e TO. Crie um modelo de dominio e utilize um repositório.
  3. Crie sempre testes, ou melhor utilize TDD efetivamente.
  4. Tente separar bem as camadas e não criar acoplamento (Se você utilizar TDD seu acoplamento entre classes será baixo, mas poderá haver acontecer entre as camadas).

Qualquer duvida, estamos ai!

Agora fiquei curioso, por que não usar?

Vou aproveitar a sugestão dos livros e ler também.

x111

Mas quem são as pessoas que programam de maneira procedural que você está falando? O Delphi não é uma linguagem procedural. Ele é orientado a objetos. Tem classes, interface, polimorfismo… A própria VCL implementa padrões de projetos como o observer, chain of responsability, mediator… Ou você se refere a programadores que vieram do Pascal (que não parece ser o caso do colega)?

Realmente, eu vim do C. Não estou dizendo que Delphi não é OO. O problema é dele é o formato de UI onde você arrasta para tela um componente TConnection da vida, um TQuery e um TDataSet, parametriza as propriedades escreve a consulta no TQuery, coloca meia duzia de Data Controls e tem um crud pronto em menos de 15 minutos! Depois é só trabalhar em cima de alguns eventos e escrever alguns métodos para alguma regra de negócio específica.

Como é extremamente rápido fazer isso e criar um modelo OO é demoria muito mais tempo a UI vence. Claro que isso tem um preço a longo prazo e só quem já passou por isso e sabe as consequências de não utilizar OO no Delphi. Só que a grande maioria das empresas (eu atuei em várias como programador Delphi) preferem manter o legado do que começar uma refatoração e nem querem pensar OO. Como disse um ex-chefe meu “Objetos é coisa de acadêmico”! Isso cria uma cultura e quem vem dela tem dificuldades em entender o paradigma OO.

Também fui programador delphi por anos, na verdade utilizo ele até hoje! Só que acredito que você teve sorte. A maioria das empresas que utilizam Delphi não o fazem usando OO! Como disse antes a maioria mantém o seu legado procedural!

ViniGodoy:
O artigo que você postou não fala nada sobre a necessidade de contagem de referências para se implementar um modelo realmente OO. Ele só mostra uma forma de implementar o mecanismo em Delphi. Gostaria de ver uma referência que relacionasse uma coisa a outra. No C++, por exemplo, existe OO sem contagem de referências.
Não vou negar que contar referências ou garbage collection simplificam muito o projeto (e daí, o artigo que vc postou e os smart pointers do C++) e que, de maneira geral, seja extremamente vantajoso ter contagem de referências. Mas contagem de referência nunca foi um requisito para um sistema ser orientado a objetos, e sistemas de performance crítica ou requisitos mais agressivos de memória frequentemente optam por não usa-la, mesmo pagando o custo da complexidade e risco de um memory leak.

Realmente não fala, a idéia foi colocar uma referência para uma implementação de contagem de referência que Delphi não tem. So que você já tentou fazer um sistema totalmente OO sem isso? É loucura, principalmente quando você tem inumeras classes compartilhadas! Existem outras formas mas a que custo? A complexidade aumenta tanto que você deixa de pensar no dominio para implementar outras coisas devido a restrições da linguagem. É possivel? Sim, mas vai ser um trabalho dos infernos!

Concerteza, mas isso acontece direto no Delphi! Acretido que a vantagem do java nesse caso é que eu nunca vi uma ferramenta tão boa para criar aplicações desktop quanto a do delphi e mesmo assim se vê muita bizarrice. Imagina só se swing tivesse alguns Data Controls :shock:

Só quero esclarecer que não considero o Java melhor do que Delphi até por que eu não acredito em melhor linguagem como escrevi aqui. Na verdade o delphi é uma linguagem fantástica e tem uma gama de recursos incriveis, porém não considero ela a melhor a linguagem para trabalhar com objetos devido a falta de gerenciamento de memória, permitir a instancia de um objeto abstrato e não permitir um construtor privado entre outros). É possivel criar programas OO no delphi? Sim, mas você vai ter uma dificuldade bem maior do que no java!

x111

Agora fiquei curioso, por que não usar?

Vou aproveitar a sugestão dos livros e ler também.[/quote]

Sobre DAO o Sérgio Taborda da uma ótima explicação aqui mesmo no forum

BOs e VOs e bem simples: Porque você esta programando de maneira procedural! Uma classe contém as regras de negócio a outra os dados então qual a diferença entre um conjunto de funções de uma biblioteca e um struct (ou record no pascal/delphi)? NENHUMA, pois um BO cheio de funções de negocio e um biblioteca cheia de funções fazem a mesma coisa já um TO (ou VO, como preferir) é quase igual a uma struct a um record exceto que esses não tem os métodos getters e setters que na verdade não servem para nada sendo mais fácil deixar os campos públicos!
Isso cria o chamado dominío anêmico onde se tem um conjunto de classes que não tem “responsabilidade nenhuma”, ou seja, um monte de clases burras!

BO e TO são uma bizarrice criada devido a arquitetura do EJB 2.0. Só que isso é tão natural para quem vem do mundo procedural e acha que sabe OO e então seguem utilizando esses padrões e, embora seja um padrão do java, já vi isso sendo utilizado até no PHP!

Aqui tem um artigo que fala mais disso

ViniGodoy

Não só tentei, como já fiz. É bem mais difícil mesmo. Exige do programador saber onde as coisas nascem e morrem.

V

x@ndy:
Vendetta:

2) Não utilize DAO, BOs e TO. Crie um modelo de dominio e utilize um repositório.

Agora fiquei curioso, por que não usar?

Vou aproveitar a sugestão dos livros e ler também.

Sobre DAO o Sérgio Taborda da uma ótima explicação aqui mesmo no forum

BOs e VOs e bem simples: Porque você esta programando de maneira procedural! Uma classe contém as regras de negócio a outra os dados então qual a diferença entre um conjunto de funções de uma biblioteca e um struct (ou record no pascal/delphi)? NENHUMA, pois um BO cheio de funções de negocio e um biblioteca cheia de funções fazem a mesma coisa já um TO (ou VO, como preferir) é quase igual a uma struct a um record exceto que esses não tem os métodos getters e setters que na verdade não servem para nada sendo mais fácil deixar os campos públicos!
Isso cria o chamado dominío anêmico onde se tem um conjunto de classes que não tem “responsabilidade nenhuma”, ou seja, um monte de clases burras!

BO e TO são uma bizarrice criada devido a arquitetura do EJB 2.0. Só que isso é tão natural para quem vem do mundo procedural e acha que sabe OO e então seguem utilizando esses padrões e, embora seja um padrão do java, já vi isso sendo utilizado até no PHP!

Aqui tem um artigo que fala mais disso

Muito Obrigado pela explicação, fiquei curioso porque participei de projetos onde era comum esse tipo de padrão.

x111

Não só tentei, como já fiz. É bem mais difícil mesmo. Exige do programador saber onde as coisas nascem e morrem.

Esse é o problema quando a linguagem não ajuda! Ao invés de se preocupar com domínio tem que se preocupar com gerenciamento de memória da aplicação. A mesma coisa se aplica ao Java, por exemplo, quanto se tenta acessar dispositivos de hardware diretamente. Vai ter que usar, JNI, JNA e talvez uma outra linguagem ainda. Por isso acho que Java não é ideal para trabalhar com acesso a dispositivos de hardware, já isso é muito fácil de ser feito com o Delphi, por exemplo!

gomesrod

Olá,

O que tenho visto nos projetos com EJB 3 é que ainda se faz dessa maneira. Alguns VOs ou DTOs para trafegar os objetos entre as camadas, e toda a lógica no SessionBean (o BO).
Qual abordagem vocês têm usado para sair do padrão “BO-VO” nos sistemas com EJB 3 ? Objetos de domínio inteligentes são transportados entre as camadas? Qual a responsabilidade do Session Bean, apenas a persistência? O design da solução é pensada de maneira diferente para ejbs locais e remotos, ou isso é indiferente?

nel

Olá,

O que tenho visto nos projetos com EJB 3 é que ainda se faz dessa maneira. Alguns VOs ou DTOs para trafegar os objetos entre as camadas, e toda a lógica no SessionBean (o BO).
Qual abordagem vocês têm usado para sair do padrão “BO-VO” nos sistemas com EJB 3 ? Objetos de domínio inteligentes são transportados entre as camadas? Qual a responsabilidade do Session Bean, apenas a persistência? O design da solução é pensada de maneira diferente para ejbs locais e remotos, ou isso é indiferente?

O objeto do VO é trafegar dados que não estão necessariamente na sua entidade (tabela). Você consegue acoplar dados que talvez você use exclusivamente a nível de apresentação sem que tenha necessidade dos mesmos serem persistidos. Dados que serão validados na sua camada de negócio antes de ser enviada a camada de persistência e evita dores de cabeça com tráfego de entidade entre várias camadas bem como possíveis problemas como “lazy collection” entre outros.

O EJB 3.1 e a especificação JEE 6 trouxeram várias injeções para facilitar o desenvolvimento e deixar o que antes era de responsabilidade do desenvolvedor como responsabilidade do servidor de aplicação, como é o caso do @Singleton.

O ideal, correto, é que o arquiteto ou, no mínimo, o analista sênior use e abuse da especificação JEE 6 no momento de definir o que será usado no projeto.
Eu trabalho com toda essa especificação JEE 6 e tem muita coisa que eu ainda não usei. Tem injeções a nível de JPA bem interessantes, de segurança (uso constante aqui) entre outros.

Mas cada projeto é um projeto, o ideal é seguir corretamente a especificação e procurar os melhores patterns para o seu caso.

ViniGodoy

Na época do C++, chamavamos VOs de structs…

nel

Eu tive dificuldades em aprender structs. No meu curso de graduação, programação já tinha no primeiro semestre e eu nunca havia lido nada sobre algoritmo, lógica de programação e muito menos programar efetivamente em alguma linguagem. Aprendemos C/C++. Tinhamos muito contato no “meio” do semestre com ponteiros e structs, nossa, como eu confundia rsrs…

No semestre seguinte tivemos “algoritmos e estrutura de dados”. Esse sim, era ponteiros “puro”, tudo para aprender filas encadeadas, filas duplamente encadeadas, FIFO, lista e etc e ao fim do semestre víamos arvore binária, o que eu também senti bastante dificuldade. São apenas comentários porque eu sei que você tem experiência de anos com C++ ViniGodoy.

Já fazem anos esse meu contato com C++, atualmente, sem consultar um Google da vida, nem “hello world” sei fazer mais rsrs…

x111

Olá,

O que tenho visto nos projetos com EJB 3 é que ainda se faz dessa maneira. Alguns VOs ou DTOs para trafegar os objetos entre as camadas, e toda a lógica no SessionBean (o BO).
Qual abordagem vocês têm usado para sair do padrão “BO-VO” nos sistemas com EJB 3 ?
Bom não sou especialista em EJB mas vamos lá… qualquer coisa por favor me corrijam.

Digamos que você tenha 4 camadas da sua aplicação:
1 - Visualização - HTML, CSS, etc
2 - Camada de Serviço - Sessions Beans
3 - Dominio - Entidades, Objetos Valor, Agregados , Repositorios, etc
4 - Persistencia. DAO (Entity Manager), Domain Store

Objetos inteligentes (Objetos do dominio) circulam normalmente entre as camadas 2 e 4 porém na camada 1 você pode necessitar de objetos auxliares para representar objetos do dominio mas sem a lógica de negócio para exibição dos dados a serem processados para visualizão

Seriam utilizados principalmente na sua Camada de Serviço fazendo o meio de campo entre a visualização e o dominio (parecido com um controller) sendo responsável pela persistência dos dados e não tendo qualquer lógica de negócio. Também é possivel utiliza-los dentro da camada de Dominio como Serviços. Nesse caso teriam lógica de negócios, mas é importante saber separar as responsabilidades e saber quando um pertence a uma camada ou a outra.

Não entendi bem o que você quis dizer com isso mas acredito que esteja falando de objetos distribuídos já que no modelo do BO isso muito utilizado e como seu Session Bean é seu BO! Bom se for isso cito a primeira lei de Fowler sobre Objetos Distribuidos: “Não distribua seus Objetos”.
Isso se deve ao fato que em um modelo de objetos ricos esses terão muitos métodos ou seja, terão uma granularidade alta, chamadas remotas a objetos de granularidade alta é extremamente lento, pois imagine chamar cada método individual de um objeto como Endereco, você não vai querer fazer isso. Dessa forma ao invés de fazer chamadas a cada método de endereço como endereco.setRua, endereco.setCidade e por ai vai você vai querer fazer endereco.setDados(rua, cidade, estado). Só que objetos de granularidade baixa como nesse caso não combinam com um modelo rico, onde a lógica está dentro do objeto.
Nesse caso, como diria Fowler: “venda sua avó favorita antes de distribuir seus objetos”, mas, caso seja extremamente necessário, utilize os padrãoes Remote Facade e Data Transfer Object (DTO)

x111
nel:
ViniGodoy:
Na época do C++, chamavamos VOs de structs...

Eu tive dificuldades em aprender structs. No meu curso de graduação, programação já tinha no primeiro semestre e eu nunca havia lido nada sobre algoritmo, lógica de programação e muito menos programar efetivamente em alguma linguagem. Aprendemos C/C++. Tinhamos muito contato no "meio" do semestre com ponteiros e structs, nossa, como eu confundia rsrs...

No semestre seguinte tivemos "algoritmos e estrutura de dados". Esse sim, era ponteiros "puro", tudo para aprender filas encadeadas, filas duplamente encadeadas, FIFO, lista e etc e ao fim do semestre víamos arvore binária, o que eu também senti bastante dificuldade. São apenas comentários porque eu sei que você tem experiência de anos com C++ ViniGodoy.

Já fazem anos esse meu contato com C++, atualmente, sem consultar um Google da vida, nem "hello world" sei fazer mais rsrs..

Por favor, VO não! TO ou DTO, VO é um Value Object, um padrão criado por Martim Fowler e não tem nada haver com o padrão JavaEE que alias foi renomeado para TO devido a isso, mas ainda existe documentação chamando de TO de VO por isso a confusão.

Um struct no C/C++ ou um Record no Pascal/Delphi é uma estrutura quase identica a uma classe sem métodos. Um TO normalmente para seguir o padrão java é um Bean e por isso tem um monte de metodos getters e setters que na verdade inuteis já que não fazem nenhuma operação. Qual a diferença entre as duas classes abaixo? Tirando que a segunda não é um Java Bean? Ambas são um TO e a segunda é igual a um struct! Adicionar os Getters e Setters para TO não faz a mínima diferança, só da mais trabalho.
public class Endereco{
  private String rua;
  private String cidade;

  public void setRua(String rua){
    this.rua = rua;
  }
  
  public string getRua(){
    return this.rua;
  }

  public void setCidade(String cidade){
    this.cidade = cidade;
  }
  
  public string getCidade(){
    return this.cidade;
  }
}
...
public class Endereco{
  public String rua;
  public String cidade;
}
Um exemplo de struct e record
struct Endereco {
    String rua;
    String cidade;
}
...
TEndereco = record
    Rua: String;
    Cidade: String;
end;
gomesrod

Vou agora me concentrar em um ponto crítico que é a “fronteira” entre as aplicações EJB e a aplicação que consome o EJB (vamos considerar que é uma Web App para facilitar)

|-------------------|
|                   |
|   Web App         |
|                   |
|    |------|       |
|    | stub |       | 
|-------------------|
         ^
         |
      objetos serializados
         |
         v
|-------------------|
|    | stub |       | 
|    |------|       |
|                   |
|   EJB App         |
|                   |
|-------------------|

Primeira dúvida, dentro daquele esquema de 4 camadas que você citou, onde entraria a Web App (servlets, actions, managed beans, etc) ? Faz parte da camada 1, ou na verdade estaria faltando citar ali uma outra camada entre a 1 e a 2 ?
Segundo: de acordo com o seu esquema esse transporte de objetos para o EJB seria entre as camadas 1 e 2? Se for desse modo, o que você diz é que se deve usar objetos auxiliares (TO/DTO) e não objetos inteligentes. Essa é boa parte da minha dúvida, devemos trafegar objetos inteligentes entre as aplicações?

Pelo que entendi aqui os EJBs delegam as operações de negócio para objetos do domínio.
Idealmente o domínio deve ser formado apenas por POJOs (classes sem nenhuma dependência com frameworks) ?

Um objeto de domínio processa as regras de negócio, e no fim é esse objeto quem comanda as operações de persistência nos momentos adequados. Correto? Nesse cenário como poderia o EJB ser responsável pela persistência se a responsabilidade pela operação de negócio já está nas mãos do objeto de domínio?

Para complicar mais um pouco vamos colocar o JPA na jogada. O EJB é quem tem o “direito” de ter uma instância do EntityManager injetada nele. É válido que ele por sua vez injete esse EntityManager nos objetos de domínio para que eles possam fazer operações de persistência (automaticamente passando a ter dependência da API do JPA)?

Esse negócio de objeto distribuído é muito bizarro… na verdade nem considero essa opção, costumo usar apenas EJBs stateless como uma interface para serviços. A dúvida é o seguinte:
Volte para aquele desenho lá em cima: quando o EJB é remoto, é necessário serializar e transportar os parâmetros e retornos dos métodos. Já no EJB local isso não é necessário, tanto o ejb quanto o cliente estão na mesma JVM e o método pode ser chamado como um método normal.
Essa diferença deve ser levada em consideração na hora de desenhar os serviços?
Tipo… quando for local deve-se optar por usar classes de parâmetro e retorno com as características “XXXXXX” , já quando for remoto procure modelá-las da maneira “YYYYYYY”…
A escolha em transportar objetos inteligentes para o EJB é afetada por esse fator ?

E quem seria doido suficiente para se declarar especialista em uma coisa dessas? :slight_smile:

x111

gomesrod:

Vou agora me concentrar em um ponto crítico que é a “fronteira” entre as aplicações EJB e a aplicação que consome o EJB (vamos considerar que é uma Web App para facilitar)

|-------------------|
|                   |
|   Web App         |
|                   |
|    |------|       |
|    | stub |       | 
|-------------------|
         ^
         |
      objetos serializados
         |
         v
|-------------------|
|    | stub |       | 
|    |------|       |
|                   |
|   EJB App         |
|                   |
|-------------------|

Primeira dúvida, dentro daquele esquema de 4 camadas que você citou, onde entraria a Web App (servlets, actions, managed beans, etc) ? Faz parte da camada 1, ou na verdade estaria faltando citar ali uma outra camada entre a 1 e a 2 ?


Se for local, tanto faz, pode haver uma camada a mais ou pode ser a camada 1. A questão é que o limite entre a 1 e a 2 é bem definido. Uma camada a mais seria mais para divisão de responsabilidades da camada 1 e não afetaria tanto a estrutura.

Só lembrando que esse exemplo de camadas é o que eu uso normalmente, pode ser necessário mais ou até menos camadas!

Pelo que entendi aqui os EJBs delegam as operações de negócio para objetos do domínio.
Idealmente o domínio deve ser formado apenas por POJOs (classes sem nenhuma dependência com frameworks) ?
Idealmente sim, embora POJO não queira disser que uma classe não dependa de um framework. Eu pessoalmente não faço isso e utilizo JPA para criar o metamodelo. É possivel criar um Data Mapper para fazer isso mas a tarefa é árdua. O Sergio Taborda até criou um framework (MiddleHeaven) para fazer essa separação. Acredito que isso só seja necessário caso se queira independência do modelo de persistência.

Sim. Ele não responsável pela persistência, somente pela lógica transacional!

Não só é valido como necessário! Ou você pode deixar o container fazer isso! Eu deixo o container ou uso CDI

Não entendi bem o que você quis dizer com isso mas acredito que esteja falando de objetos distribuídos
Esse negócio de objeto distribuído é muito bizarro… na verdade nem considero essa opção, costumo usar apenas EJBs stateless como uma interface para serviços. A dúvida é o seguinte:
Volte para aquele desenho lá em cima: quando o EJB é remoto, é necessário serializar e transportar os parâmetros e retornos dos métodos. Já no EJB local isso não é necessário, tanto o ejb quanto o cliente estão na mesma JVM e o método pode ser chamado como um método normal.
Essa diferença deve ser levada em consideração na hora de desenhar os serviços?
Tipo… quando for local deve-se optar por usar classes de parâmetro e retorno com as características “XXXXXX” , já quando for remoto procure modelá-las da maneira “YYYYYYY”…
A escolha em transportar objetos inteligentes para o EJB é afetada por esse fator ?
Cara você pode não considerar mas parece isso que você está fazendo! Nesse caso você faz exatamente o exemplo acima, só adicionaria uma uma fachada para tornar essa comunicação transparente.

ViniGodoy

Sim, usei o termo no contexto que estavam falando, que era como era falado em JavaEE antigamente.
De qualquer forma, TO e DTO são structs serializable (em C++ elas são por padrão) e const.

E o famoso “modelo anêmico” é exatamente o que fazíamos em programação estruturada, só que com uma sintaxe mais leve, simples e concisa.

x111

Sim, usei o termo no contexto que estavam falando, que era como era falado em JavaEE antigamente.
De qualquer forma, TO e DTO são structs serializable (em C++ elas são por padrão) e const.

E o famoso “modelo anêmico” é exatamente o que fazíamos em programação estruturada, só que com uma sintaxe mais leve, simples e concisa.

Verdade! Sempre que eu vejo um projeto anêmico em java tenho o seguinte dialogo:

  • “Por que você usam beans para TO?”
  • “Porque é o padrão!”
  • “Tá mas se é o padrão vamos usar OO de verdade e passar o a logica desses BO para dentro desses BOs”
  • “Não dá, porque o padrão é usar BO”!
  • “Tá, mas e a orientação a objetos?”
  • “Tá ai, estamos utilizando Beans, TOs, BOs, tudo dentro do padrão!”

As pessoas não entendem a diferença entre usar objetos e programar orientado a objetos. Se é para programar de forma estruturada então, pelo menos que se faça direito e não se use mais Beans!

Criado 26 de março de 2013
Ultima resposta 27 de mar. de 2013
Respostas 32
Participantes 6