Antes que alguém diga que estou tentando adotar soluções complexas para um problema simples, este projeto tem como finalidade o estudo de orientação a objeto.
Baseado-se no modelo de domínio em anexo e na utilização dos padrões: Modelo de domínio, Camada de Serviço e Repositório.
Requisito:
O meu cliente deseja ter a facilidade adicionar lojas ao shopping.
“Ooo como é difícil persistir e recuperar objetos de forma sadia para a orientação a objeto!”
Dentre várias soluções que eu pensei vou citar 2 delas. E gostaria que vocês avaliassem não só as soluções mais também as contra-indicações que eu penso que elas possam me trazer.
1 solução: Fazer com que a coleção de lojas do shopping seja implementada como um repositório. Mas como eu persistiria o nome do shopping? Criar um repositório só para persistir o nome do shopping acho um pouco estranho. Eu tendo a ver repositórios como coleções e nome não é uma coleção.
2 solução: Criar uma camada de serviço para o shopping e criar um repositório para o shopping. Fazer com que a camada de serviço gerencie a persistência do shopping (A camada de serviço ira chamar métodos como repositorioShopping.atualizar(shoppingL)). Mas imagina eu adiciono uma loja no shopping e chamo o repositorioShopping.atualizar(shoppingL), vou ter que fazer varias verificações para saber o que alterou no shopping “Nada eficiente eu acho”. Posso também colocar no repositório o método repositorioShopping.addLoja(shoppingL.getLoja(_idNovaLoja)), acho que essa solução não fica lá muito cheirosa, ainda mais porque acho que não faz muito sentido ficar com lojas em memória. Tendo em vista isso não, faz sentido eu adicionar uma loja no shopping e depois coloca-la no repositório e ainda sim ela continuar no objeto shopping em memória.
Se vocês quiserem me recomendar outras soluções, criticar as minhas, acrescentar algo nas minhas ou até citar fontes para estudo eu agradeceria muito!
[quote=brunohansen]Requisito:
O meu cliente deseja ter a facilidade adicionar lojas ao shopping.
[/quote]
Seu sistema administra muitos shoppings?
Seu modelo diz que o shopping é uma loja que possui lojas. Porque você enxerga que um shopping é uma loja? Quais comportamentos e dados você espera que eles tenham em comum? Eu não modelaria assim. Se Lojas e Shoppings possuem características em comum eu criaria uma superclasse “Empresa”. Conceitualmente é estranho falar que o Shopping é uma Loja.
Vejo que o modelo do jeito que está vc teria um repository de lojas para obter e adicionar lojas e shoppings (afinal o shopping é uma loja). Uma loja pode estar associada a dois shoppings diferentes?
É estranho a um repository ter uma operação atualizar. Repositories geralmente retornam uma ou mais entities. Se eu altero uma entity, abstratamente, significa que os dados já são alterados no banco sem precisar chamar um salvar. Mas isso a sua arquitetura deve resolver.
O mesmo digo para a manutenção entre shopping e loja. O Shopping tem uma operação addLoja(Loja). A persistência do relacionamento não deveria ser responsabilidade do repository.
rss… Meu sistema administra um único shopping com centenas de lojas.
Uff ainda bem que meu modelo esta passando o que eu quero expressar!
É eu realmente vejo que Shooping e um tipo especial de lojas. Os comportamentos e dados que eles tem em comum é poder ser adicionados varios endereços, telefones, e-mail. Uma caracteristica que Shopping possui que loja não tem é poder ter varias lojas (Adicionar e remover lojas), para mim isso o torna um tipo especial de loja.
Ao meu ver não seria bacana eu utilizar um repositorio de loja para guardar shopping pois shopping tem algo a mais que loja.
Uma loja não pode estar associada a dois shoppings diferentes, até porque meu projeto inicialmente so vai gerenciar um shopping como dito acima.
O que vai acontecer mais para frente no meu projeto, só que não quis mencionar para simplicar, é que meu shopping vai ter varias categorias e as lojas deveram participar de uma ou mais categorias do shopping.
Isso me parece um pouco com auto save. E eu não queria acoplar tudo quando é objetos a repositorios.
Quanto a operação atualizar não acho que seja tão estranho assim, muitas pessoas utilizam algo como uma operação save que era oq minha operação atualizar querias expressar.
Vou procurar uma referência para atualização de objetos em repositorios e depois menciono aqui.
Voce neste topico http://www.guj.com.br/posts/list/15/33027.java, mencionou que estava pensando em fazer algo genérico para persistencia de objetos de domínios e fazer que seus objetos de dominio herdar de PersistentDomainClass. Eu particularmente não gostari de fazer isso pois eu estaria gastando minha unica possibilidade de herança com persistencia e estaria acoplando meus objetos de dominio com um meio de persistencia. (Mesmo sendo abstrato estarei acoplando e gastando minha unica herança permitida pelo java).
Não entendi esta parte! Eu estava pensando que como meu shopping tem um repositorio de lojas quando eu adiciono uma loja a esse repositorio, eu ja estou fazendo um relacionamento entre loja e shopping pois o repositório onde a loja foi adicionado é do shopping.
Para finalizar gostaria de lhe agradecer muito todas as ajudas que você particulamente tem me dado em todos os topicos que eu posto e pela sua paciencia em exclarecer minhas dúvidas. Espero um dia poder quitar essa divida com vc. Valew mesmo pela força que vc tem me dado.
Bruno, uma coisa que você tem que ter em mente é que objetos não precisam ser persistidos. Não no mundo deles.
Se falarmos simplesmente de objetos tudo é sempre persistente. Persistência como conhecemos em TI (bancos de dados, xml, etc.) é apenas uma alternativa à limitação que é não podermos ter objetos sempre em memória.
Partindo deste ponto, um sistema que leve OO a sério vai tratar todos os objetos como se eles fossem permanentes sempre, por isso coisas como ‘atualizar’ são desnecessárias conceitualmente. Apagar é uma exceção porque apagar é eliminar todas as referências um objeto e isso não é simples, mas vamos passar essa por enquanto.
E já que isso é um sistema real e não vive no antástico mundo de bobject, quando persistir os objetos?
Se você puder escolher, use um frameworkde ORM como JPA ou Hibernate. Estes vão permitir que você abstraia isso e cuidam e atualizar objetos quando transações se encerram.
Se você vive no mundo negro do JDBC puro as opções são restritas. Você poe tenatr criar um framework caseiro que detecte os objetos que foram alterados e os atualize automaticamente interceptando o fim do caso de uso/use story, mas isso tende a erros e costuma ser bem ineficiente.
Utilizando JDBC eu ainda não achei nada que substituísse o atualizar() com eficiência. Geralmente o que eu faço quando quero um modelo mais limpinho é tornar objetos persistíveis subjects e um DAO/Repository observer. Isso é meio drástico e trabalhoso, mas com AOP pode ser meis simples, principalmente se você adotar convenções para nomes de métodos que mudam o estado do objeto ou -muito melhor- usar annotations pra isso (em Ruby seria bem fácil :P).
você não acha que um BDOO não seria mais fácil de utilizar objetos persistentes, e também transientes ?
Tratar O.O. a sério é ter uma visão realmente O.O. e não relacional determinada pelo modelo de dados.
Se fossemos pensar em objetos do mundo real, os dados estão intrisicamente dependentes dos objetos, um Loja por exemplo possui uma Coleção de produtos e uma coleção de clientes, sendo situada em um determinado endereço, podendo ou não ser em um shopping.
Um shopping tem um coleção de salas alocadas para determinadas lojas, isso me faz ver um modelo em forma de objetos com um visão mais em forma de grafos do que relacional.
Os dados que são hoje em dia armazenados em um local como um banco relacional, foi devido ao seu uso intensificado pela maioria das empresas, e antes ainda não se falava muito em O.O. era mais linguagem procedural, e os retornos eram feitos em Arrays[][].
Meu ponto de vista é: Unificar duas visões de modelagem diferentes acaba não aproveitando todos os benefícios dessas visões.
[quote=Fabrício Cozer Martins]
você não acha que um BDOO não seria mais fácil de utilizar objetos persistentes, e também transientes ?
[/quote] Não os que eu conheço, e eu conheço alguns. Na verdade eles só complicam.
Acho que você não entendeu o problema.
Impedance mismatch é um problema sim, mas a tecnologia atual já consegue resolve-lo de maneira altamente satisfatória. exceto por problemas de performance com relatórios não é muito comum achar um caso onde o programador não fique livre para usar OO usando transações declarativas com uma boa engine de ORM.
O maior problema neste caso nao é do SGBDR em si mas sim da maneira como ele é utilizado. Pensar em bancos de dados como repositórios compartilhados por aplicações diversas é besteira e ainda é feito. O uso de views para integração deva estar previsto no código penal.
O ponto é que se você passa a pensar no SGBDR apenas como o lugar onde seus objetos, da sua aplicação/componente/serviço dormem, os problemas de impedância não são graves. A necessidade de um SGBD OO passa a ser próxima da de um filesystem OO para serialização de objetos.
usar um SGBDR pode não ser a melhor coisa mas:
1 - BDOO não possuem qualidade de produção IMHO
2 - SGBDR são muito performáticos e atendem à demanda
3 - É muito mais fácil convencer seu cliente a usar um
Mas este não é o problema. O problema é como sincronizar as atualizações feitas num modelo OO em outro, seja relacional, OO ou o que for, que está em um sistema independente.
Segundo especialistas isso é possível, pelo menos entre BDOO e BDR, a Caché mesmo usa o conceito de Banco de Dados Pós Objeto Relacional, que visa manter a integridade de informações persistidas em um BDOO com BDR, isso porque o pessoal sabe que essa migração deve ser feita de forma adaptativa, mas acho que a tendência é essa.
Se eu perguntar aqui, quem já quebrou a cabeça nos frameworks ORM, no mínimo 9 em cada 10 pessoas responderão que sim. É um saco fazer esse mapeamento, é gambiarra na metodologia O.O., meus objetos tem que se adaptar ao modelo de conjuntos que é o modelo ER.
Pode ser que os banco relacionais sejam mais performáticos do que os O.O., mas ainda não vi benchmarks satisfatórios que me provem a não utilização desse modelo.
Fazendo um pouco de merchandising do db4o.
Alguns clientes pequenos que empregam a utilização de BDOO.
BMW
Boeing
Bosch
Hertz
Altana
IBM
Seagate
Intel
E o Benchmark:
Lógico que ninguém é maluco de usar um BDOO para gerar milhares de relatórios… mas quando você tem uma aplicação atípica dessas que precisa modelar seu problema realmente O.O. a vantagem é bem maior.
Não entendi o que isso de integrar BDOO com BDR tem a ver com a discussão. Ah, e qualquer coisa é possível, o que n"ao quer dizer que seja simples, prático, viável…
Você nunca usou um BDOO em produção, né? Bem, eu já usei e te digo que é uma bela porcaria, tanto que um dos projetos da empresa era migrar para Oracle. Os tais especialistas e estas estatísticas sem pesquisa não dizem muito da realidade prática das coisas. Existem dificuldades em dominar ORM assim como existe dificuldade em dominar OOP, na verdade essa última é a maior causa de problemas na primeira.
Novamente lá vamos nós: este não é o problema abordado neste tópico. Mesmo assim, na minha experiência BDOO sempre é muito menos performático que SGBDR, mesmo porque tem, teoricamente, mais recursos.
Emrpegam onde? No sistema de agenda de contatos? Essa lista não quer dizer absolutamente nada sem os casos reais explicados.
Ah meu Zahl, mais benchmarks feitos só pra chamar atenção. Tá, me msotra isso num caso real, daí conversamos. Do contrário eu pego os benchmarks da Microsoft e vou usar .Net que é mais performático que Java segundo eles.
Por que é bem maior?
1 - O que eu não preciso fazer? Qual o preço disso?
2 - Como esse banco OO se integraria com meu Domain Model?
3 - Qual problema um ORM n"ao está te solucionando?
Cuidado com o marketing dos fornecedores e os sonhos da academia.
E pronto, o assunto descambou rpa algo que não tem nada a ver…
Isto já quase faz parte da minha mente, mas é difícil projetar algo que não transpareça que eles são persistidos!
Eu quero fazer sistemas que leve OO a sério!
Mas como informar para a camada que vai cuidar da persistencia que o estado do meu objeto alterou e ele deve ser salvo! Tudo isso sendo transparente para o meu modelo de domínio! UFFffff…
Dei uma olhada sobre Hibernate em alguns tutorias aqui do GUJ (Sou inexperiente com Hibernate) e nenhum deles de um exemplo sobre o que acontece quando um objeto altera seu estado!
O Hibernate detecta que o estado de um ojeto mudou e o persiste automaticamente? Como ele faz isso, se faz? Acho que usar anotações fere um pouco o conceito OO!
Se puder me recomendar algo sobre Hibernate para eu ler…
Acho que viver no mundo negro traz muitas experiências boas a nivel de conhecimento de soluções!
Observers realmente é uma boa trabalhosa solução! Já tinha pensado nisso, só que algo me dizia que era meio loucura…
Voltando a finalidade deste tópico.
Então shoes no mundo negro voce usaria observers ou um metodo atualiar nos repositorios?
E no objectLand qual seria sua solução? Aspectos?
ahh outra coisa o que você acha melhor colocar metodos de atualização em repositorios ou tornar meus objetos de dominio registro ativos colocando métodos save e delete neles?
E voces galeras o que voces fariam no mundo negro no objectland??? Da sua opinião ai Rodrigo e Fabrício!
Com relação ao debate do shoes com o Fabrício vou me abster pois não tenho experiencia para isso e meu foco principal aqui é algo mais básico rs…
Sim, o Hibernate detecta mudanças em objetos persistentes. Consulte a documentação que é boa e tente descolar o Hibernate in Action.
Quanto 'a JDBC, eu n|ão uso JDBC em sistemas que não sejam CRUDs muito simples, não há um motivo que justifique o não uso de um ORM, exceto se não te deixarem. Utilizar JDBC é mortal porque você não tei Lazy Loading e isso torna a realição dos seus casos de uso completamente atrelada ao JDBC e persistência, quando deveria ser persistente.
Sim, utilizar JDBC te ensina muito. Programar seu próprio Sistema Operacional ou JVM também ensina muito. O ponto é saber dividir o que é aprender e o que é usar em produção.
Eu já trabalhei em sistemas muito grandes com JDBC e me arrependo amargamente de não ter insistido em usar Hibernate, o 2 ainda na época.
Então shoes no mundo negro voce usaria observers ou um metodo atualiar nos repositorios?
E no objectLand qual seria sua solução? Aspectos?
ahh outra coisa o que você acha melhor colocar metodos de atualização em repositorios ou tornar meus objetos de dominio registro ativos colocando métodos save e delete neles?
E voces galeras o que voces fariam no mundo negro no objectland??? Da sua opinião ai Rodrigo e Fabrício!
Será que desta vez consigo uma resposta??? :shock: :?:
Tenho que conseguir, porque se eu depender das minhas interpretações vou seguir pelo caminho mais louco!!! hauahahuahha
Não, ainda não, mas provavelmente os fluxos das melhorias na forma de desenvolver levam a utilização de um BDOO, pretendo aplicar inicialmente em um micro-projeto, onde os riscos são menores e com isso poderemos futuramente concebê-los em aplicações de grande porte, que se encaixem nos requisitos de utilizar um BDOO. Com o uso de um BDOO, o projeto O.O. deve ser bem desenhado, pois isso implicaria em queda de perfomances, pode ser essa baixa performance que você mencionou mais acima.
1-) Não precisa criar diagramas de dados relacionais, não precisa se preocupar com a visão orientada a relações de conjuntos, o desenvolvimento é trilhões de vezes mais rápidos, as empresas não precisaram ter que desenhar um diagrama de dados de visão, outro físico, basta desenhar o diagrama de classes, onde o mesmo de forma bem representada estará sendo bem fiel ao mundo real onde a aplicação se contextualiza.
O banco OO já é seu Domain Model, não precisa se preocupar em mapear quais são os campos persistidos ou não, apenas precisaria utilizar um BDOO, que certamente terá APIs para utilização do mesmo na própria linguagem, como ocorro no db4o.
Nenhum, posso resolver os problemas até usando linguagens procedurais que vou conseguir fazer o sistema funcionar, mas hoje em dia queremos cada vez mais melhorar a forma de desenvolver, a engenharia da computação prega isso, como o caso de AOP, que visa retirar o entrelaçamento do código, os BDOOs visam tirar a duplicidade de visões e aplicar seriamente a O.O. nos projetos.
Ok partindo dessa premissa a persistencia é algo q deve ser o mais tranparente possível certo? Ao ponto que isso não deveria estar refletido no meu domain model.
Então basicamente um repositório que isola a persistencia tem um método para criar (e algumas variantes) e métodos de busca.
Dessa forma o correto seria modelar o domain model sem se preocupar com persistencia, já q ela é uma constante e nesse caso o repositório terá de se virar e ir acrescentando a ele métodos para busca específicas (ou usar os métodos genéricos até onde der).
E apenas depois quebrar a cabeça para persistir isso de forma eficiente, ainda mais qdo algumas modelagens onde tem um objeto em várias tabelas e vice-versa.
As perguntas são pq eu vejo muito as pessoas modelando DAOs e objetos de negócio e sempre se preocupando com o banco de dados e as tabelas, sim é uma preocupação relevante, mas num domain model ela deveria ser secundária e vir depois, ou será q estou confundindo tudo e estou errado aqui?
Fabrício, um banco OO não oferece tanta vantagem quanto você acha. Principalmente quando se fala em uso em larga escala. Alguns do vários problemas que se encontra no dia a dia trabalhando com esse tipo de banco.
-O modelo OO não é tão expressivo quanto o relacional quando o assunto é representação de informação.
-A transparência para a aplicação é a mesma que de um RDBMS, o desenvolvedor tem que continuar se preocupando em chamar os métodos de persistência ou usar algum esquema ninja como aqui discutido para aumentar a transparência.
-Quando você passa a ter aplicações com ciclios de vida diferentes acessando a mesma base OO, problemas de versionamento e mapeamento continuam existindo.
Bruno, é extremamente recomendável que você use ORM como o Hibernate. Apesar de parecer, isso não é tão complicado quanto parece e as facilidades são muitas. Já faz um bom tempo que não desenvolvo no lado negro, mas quando desenvolví deixei as coisas mais simples e chamei um atualizar(). Mas já digo que isso dá muito trabalho. Se quiser fazer um LazyLoad vai ter que implementar proxies na mão. É um saco. Burocrático…
Sobre DBOO, desde os anos 90, nos primórdios do Delphi, ouço histórias sobre um mundo de fantasia… Ouvi até que quando lançaram um primeiro DBOO as ações da Oracle cairam… Teve uma leva de trainees que contratei na Datasul que nem se importaram em aprender SQL na universidade, eles estavam esperando o boom do DBOO. Tivemos que ensinar a teoria relacional para eles. Sinto dizer, mas C.J.Date ainda vai perdurar por um tempo… Pare para pensar: O modelo relacional praticamente não tem limitações quando o assunto é guardar dados…
Queria saber de vocês a opinião sobre Prevalência e o que difere de um DBOO…
Eu uso ORM o máximo possivel, com um pouco de experiência você descobre que é facil conseguir boa performance para cargas OTLP. A nova versão do hibernate quebra um galho para cargas OLAP, mas ainda assim as vezes a diferença de performance entre escrever um SQL de 5 páginas e um HQL de 2 é gritante.
[quote=Fabrício Cozer Martins]Com o uso de um BDOO, o projeto O.O. deve ser bem desenhado, pois isso implicaria em queda de perfomances, pode ser essa baixa performance que você mencionou mais acima.
[/quote]
Não, não foi.
A - Gere documentos que agreguem valor e não mil modelos só por gerar
B - Deixe o Hibernate criar teu schema e você n"ao precisa mais se preocupar com isso.
A - O banco não é seu Domain Model, ele guarda seu Domain Model assim como gaurda outras instâncias persistentes
B - Um ORM te dá uma API em Java, qual o problema? Você não precisa nem saber SQl para usar Hibernate
[quote=Fabrício Cozer Martins]
3) Nenhum, posso resolver os problemas até usando linguagens procedurais que vou conseguir fazer o sistema funcionar, mas hoje em dia queremos cada vez mais melhorar a forma de desenvolver, a engenharia da computação prega isso, como o caso de AOP, que visa retirar o entrelaçamento do código, os BDOOs visam tirar a duplicidade de visões e aplicar seriamente a O.O. nos projetos.[/quote]
IMHO você está se preocupando com um não-problema. Não é a inexistência de um SGBDOO que preste que faz os sistemas OO serem procedurais, são as pessoas que os desenvolvem.
Sim e não. um Repositório do Fantástico Mundo de Bobject™ não precisaria porque os objetos são criados, atualizados e apagados automaticamente.
Por limitações da tecnologia atual, dependendo do que você usar vai ter que ter um métiodo atualizar. Um método ‘criar’ e um ‘deletar’ é quase que onipresente em qualquer infra.
Exato. Para evitar muitos métodos de busca use o pattern Specification/QueryObject.
[quote=Edufa]
sempre se preocupando com o banco de dados e as tabelas, sim é uma preocupação relevante, mas num domain model ela deveria ser secundária e vir depois, [/quote]
Minha principal dificuldade em relação a persistencia de objetos é em relação a:
métodos de consulta:
- como passar filtros complexos ?
- como passar parametros de ordenação quando o caso de uso exige ?
- como passar parametros de paginação quando o caso de uso exige ?
- criar métdos especificos ou mais genéricos ?
retorno
como criar objetos de retorno que trazem informações de paginação ?
como estruturar objetos em relação a consultas com agrupamento ?
usar DTO ou não ?
Pessoal são dúvidas que eu gostaria de sanar.
Gostaria da opinião de vocês.
Tomara que você consiga sanar suas dúvidas porque assim eu sano algumas das minhas… O Difícil vai ser conseguir tirar o foco dos caras de banco de dados relacional vs banco de dados orientados a objetos, não sei porque sempre que se levanta qualquer questão sobre persistencia de objetos as discuções cai pra essa disputas e muito sobre soluções é discutido, sendo que para mim é o que seria maneiro… mas vou ficar no meu básico e vou tentar extrair o máximo possível dessas dicussões e aprender no teste e erro…