DDD + NoSQL é válido?

Olá pessoal!

Estou lendo o livro “Patterns of Enterprise Architecture” do Martin Fowler e lá li um pouco sobre o Domain Model. (Inclusive já vou comprar o livro do Evans pra ler depois desse :stuck_out_tongue: )

Achei interessante e resolvi abrir esse tópico para discutir com vocês a seguinte questão: Pelo que entendi, ele cita no livro que um dos pontos “chatos” de se usar um Domain Model é a complexidade para mapeá-lo na camada de persistência (problema no qual ele sugere o uso de um “Data Mapper”).

Alguém ai já utilizou Domain Model em algum projeto? Ele se tornou complexo a ponto de ser difícil para mapeá-lo ao banco de dados relacional? E qual estratégia vocês adotaram pra contornar o problema?

Outro ponto, hoje temos tecnologias NoSQL ficando cada vez mais famosas. Combinar um Domain Model com bancos schemaless (MongoDB por exemplo) facilitaria o mapeamento do domínio para a camada de persistência? E pra misturar NoSQL com RDBMS, até que ponto vale utilizar qual tecnologia?

Abraços :slight_smile:

[quote=Leonardo Gaona]Olá pessoal!

Estou lendo o livro “Patterns of Enterprise Architecture” do Martin Fowler e lá li um pouco sobre o Domain Model. (Inclusive já vou comprar o livro do Evans pra ler depois desse :stuck_out_tongue: )

Achei interessante e resolvi abrir esse tópico para discutir com vocês a seguinte questão: Pelo que entendi, ele cita no livro que um dos pontos “chatos” de se usar um Domain Model é a complexidade para mapeá-lo na camada de persistência (problema no qual ele sugere o uso de um “Data Mapper”).

Alguém ai já utilizou Domain Model em algum projeto? Ele se tornou complexo a ponto de ser difícil para mapeá-lo ao banco de dados relacional? E qual estratégia vocês adotaram pra contornar o problema?

Outro ponto, hoje temos tecnologias NoSQL ficando cada vez mais famosas. Combinar um Domain Model com bancos schemaless (MongoDB por exemplo) facilitaria o mapeamento do domínio para a camada de persistência? E pra misturar NoSQL com RDBMS, até que ponto vale utilizar qual tecnologia?

Abraços :slight_smile: [/quote]

Na teoria, abstratamente e apenas olhando a orientação a objetos, o Domain Model é um conjunto de classes que podem definir comportamento e dados. Os dados de um sistema são normalmente relacionados a persistencia ( nem sempre). Portanto, em algum ponto, esses dados têm que ser gravados em algum lugar. O padrão clássico para isso é o Memento. Um objeto memento é um objeto que apenas tem os dados e é usado como “uma imagem” da entidade original. Um memento pode ser um Pojo ou um Map, por exemplo. E o Memento é feito para ser persistido.

Então ha a necessidade de mapear os objetos do Domain model, chamados de entidades, para os seus mementos e depois de volta. É isso que o DataMapper faz.

Isto é OO. Puro e duro. Não estamos envolvendo nenhuma tencologia.

Porque o Domain Model , ele mesmo , não é persistido e existe apenas como abstração na memoria, e o memento é desacoplado desse modelo pelo DataMapper, a persistencia pode ser feita onde vc quiser. Seja SQL ou NoSQL, XML, word, excel, txt, cvs , o que vc quiser. mas toda a persistencia depende de um meta-modelo chamado “modelo de dados”. Se vc usar arquivos cvs, por exemplo, é um arquivo por tipo de memento ou um arquvio para todos os tipos ? Essas coisas têm que ser definidas e controladas em separado do modelo do dominio, pois se vc quiser mudar de cvs para SGBD ou para MongoDB o seu Domain não deve ser modificado ( é isso significa estar desacoplado).

No mundo java , existem restrições no sentido que os frameworks mais conhecidos fazem apenas um tipo de mapeamento e são especilaizados em um tipo de persistencia. O JPA , por exemplo, é especilizado em persistir em SGBD via SQL. O SpringDAta por exemplo, tenta oferecer uma solução para vários, diferentes tipos. Mas todos eles usar anotações em classes para conseguir isso. Tecnicamente, estas classes onde estão as anotações são os mementos e você está definindo como gravar e ler esses mementos com a tecnologia que vc escolheu. Não são um verdadeiro Domain Model pois não são desacoplados.

Na prática isso significa que as pessoas acham que estão fazendo DDD e usando um Domain Model, mas na realidade estão apenas usando mementos e sistemas de gravação/leitura de dados. Se vc mudar o modelo de persistencia (por exemplo trasnforma uma tabela em duas) vc tem que alterar seus mementos para que a estrutrua seja a mesma, não ha desacoplamento. e pior que isso, não ha um Domain Model que permanece inalterado seja qual for a persistencia. Ou seja, na prática ninguém (a grande esmagadora maioria) não usa Domain model nem Data Mapper. Apenas mementos e mapeamentos. E os vendors sabem disso. Eles apenas não lhe dizem. Repare que é ORM (objetc-relacional-mapping) e não DRM ( domain-relacional-mapping). ORM não são Data Mappers no sentido que o Fowler falou pois não ha realmente um Domain Model, ha apenas estruturas de dados.

Estas estrutruas de dados são necessárias e uteis e inevitáveis. E as pessoas só usam elas. Alguns dizem que isto gera um modelo “anémico”. Mas a verdade é que o problema é que não está sendo criado um Domain Model real e está-se confundindo o modelo de dados pelo modelo de dominio. É como confundir um ciclista por um goleiro e dizer que ele está fora de forma porque não sabe defender o gol. Parece lógico, mas se vc pensar bem, é puro nonsense.

[quote=sergiotaborda]Na teoria, abstratamente e apenas olhando a orientação a objetos, o Domain Model é um conjunto de classes que podem definir comportamento e dados. Os dados de um sistema são normalmente relacionados a persistencia ( nem sempre). Portanto, em algum ponto, esses dados têm que ser gravados em algum lugar. O padrão clássico para isso é o Memento. Um objeto memento é um objeto que apenas tem os dados e é usado como “uma imagem” da entidade original. Um memento pode ser um Pojo ou um Map, por exemplo. E o Memento é feito para ser persistido.

Então ha a necessidade de mapear os objetos do Domain model, chamados de entidades, para os seus mementos e depois de volta. É isso que o DataMapper faz.

Isto é OO. Puro e duro. Não estamos envolvendo nenhuma tencologia.

Porque o Domain Model , ele mesmo , não é persistido e existe apenas como abstração na memoria, e o memento é desacoplado desse modelo pelo DataMapper, a persistencia pode ser feita onde vc quiser. Seja SQL ou NoSQL, XML, word, excel, txt, cvs , o que vc quiser. mas toda a persistencia depende de um meta-modelo chamado “modelo de dados”. Se vc usar arquivos cvs, por exemplo, é um arquivo por tipo de memento ou um arquvio para todos os tipos ? Essas coisas têm que ser definidas e controladas em separado do modelo do dominio, pois se vc quiser mudar de cvs para SGBD ou para MongoDB o seu Domain não deve ser modificado ( é isso significa estar desacoplado).

No mundo java , existem restrições no sentido que os frameworks mais conhecidos fazem apenas um tipo de mapeamento e são especilaizados em um tipo de persistencia. O JPA , por exemplo, é especilizado em persistir em SGBD via SQL. O SpringDAta por exemplo, tenta oferecer uma solução para vários, diferentes tipos. Mas todos eles usar anotações em classes para conseguir isso. Tecnicamente, estas classes onde estão as anotações são os mementos e você está definindo como gravar e ler esses mementos com a tecnologia que vc escolheu. Não são um verdadeiro Domain Model pois não são desacoplados.

Na prática isso significa que as pessoas acham que estão fazendo DDD e usando um Domain Model, mas na realidade estão apenas usando mementos e sistemas de gravação/leitura de dados. Se vc mudar o modelo de persistencia (por exemplo trasnforma uma tabela em duas) vc tem que alterar seus mementos para que a estrutrua seja a mesma, não ha desacoplamento. e pior que isso, não ha um Domain Model que permanece inalterado seja qual for a persistencia. Ou seja, na prática ninguém (a grande esmagadora maioria) não usa Domain model nem Data Mapper. Apenas mementos e mapeamentos. E os vendors sabem disso. Eles apenas não lhe dizem. Repare que é ORM (objetc-relacional-mapping) e não DRM ( domain-relacional-mapping). ORM não são Data Mappers no sentido que o Fowler falou pois não ha realmente um Domain Model, ha apenas estruturas de dados.

Estas estrutruas de dados são necessárias e uteis e inevitáveis. E as pessoas só usam elas. Alguns dizem que isto gera um modelo “anémico”. Mas a verdade é que o problema é que não está sendo criado um Domain Model real e está-se confundindo o modelo de dados pelo modelo de dominio. É como confundir um ciclista por um goleiro e dizer que ele está fora de forma porque não sabe defender o gol. Parece lógico, mas se vc pensar bem, é puro nonsense.
[/quote]
Sergio, uma coisa que eu tenho usado já algum tempo e com bastante sucesso é um modelo hibrido. Crio meu Domain Model e depois começo a fazer o mapeamento das entidades deste para o modelo relacional. Minha base de dados se torna apenas um repositório de dados para o sistema e normalmente não me preocupo muito com a normalização. Nesse caso o Domain Model fica dependente do modelo de persistência (Relacional), pois não seria fácil muda-lo para outro modelo, mas tem um fraco acoplamento já que ele não é uma representação fiel da estrutura do banco!

Embora não seja uma solução perfeita, com isso eu consigo ter o melhor dos dois mundos e facilmente! Claro que não se têm a independência do sistema de persistência, mas sinceramente não me preocupo com isso pois nunca trabalhei em um sistema que tive-se que ser independente da tecnologia de armazenamento porém não tenho um modelo anêmico onde as lógica das classes estão separadas dos dados!

Outra maneira de dizer “hibrido” é dizer “acoplado”.

[quote]
Embora não seja uma solução perfeita, com isso eu consigo ter o melhor dos dois mundos e facilmente! Claro que não se têm a independência do sistema de persistência, mas sinceramente não me preocupo com isso pois nunca trabalhei em um sistema que tive-se que ser independente da tecnologia de armazenamento porém não tenho um modelo anêmico onde as lógica das classes estão separadas dos dados![/quote]

Você é consciente que seu sistema está acoplado ao bando de dados na tecnologia de JPA/JDBC/SQL. E vc sabe que seria muito problemático mudar isso para um NoSQL, por exemplo. Então vc sabe que tem um risco no seu design.
O que vc está dizendo é “como nunca no passado tive que mudar de persistencia, então nunca no futuro irei precisar, e portanto, meu risco é baixo porque a probabilidade de acontece é baixa, embora o impacto do risco seja proibitivo”.

ainda bem que vc sabe isso. Espero que o dono do produto também saiba :slight_smile:

Quando o dono do produto precisar mudar para NOSQL e vc lhe dizer que ira custar um milhão de reais :wink: ele vai lhe dizer “tiro do seu salário, pq vc fez um design ruim” :wink:
E ai vc fala : “me demito” :lol: :lol: :lol:

NO mundo real onde as pessoas se procupam com os investimentos que fazem e vêm o código e o sistema como um asset esta solução não é ideal porque o risco é muito grande ( o risco é o produto da probabilidade pela severidade - quanto custa) então 0.000001 % x 1 milhão = 1 real. Parece pouco ( pq eu chuteis os numeros. com numeros), mas não é zero.

Eu entendo o que vc quer dizer e o meu ponto que se entenda que isso é um trade-off que vc fez, mas todo o trade-off tem um risco. E é bom saber mensurar esse risco. Pois só assim a decisão do trade-off será justificável :slight_smile:

Mas agora pense quando custa minimizar esse risco ? Quando custa implementar um domain model separado e um data mapper no meio ? Tlv seja trivial , tlv não seja, mas com certeza é mais barato que reescrever tudo de novo daqui a 5, 10 anos porque o mundo só usa NoSQL … :slight_smile:

Sergio,

A idéia é que os objetos do domínio sejam apenas focados na lógica de negócio correto?

Pelo que vi nos exemplos do Fowler (simples, ele próprio admite) do ponto de vista do programador, fica uma linguagem muito mais voltada para o negócio, simples de ser entendida (desde que você entenda do domínio, obviamente). No exemplo não se há a menor preocupação sobre como ou onde os dados são persistidos.

Fazer com que o DataMapper consulte em uma camada qualquer sem afetar o domínio seria o ideal? Desde que mudanças na camada de persistência não causem alterações nos objetos do domínio.

Apenas o DataMapper consegue resolver isso? Fazer essa ponte sem criar o acoplamento entre o domínio e a persistência? Ou o DataMapper em si não pode criar instâncias do domínio?

(Confesso, ainda não li o DataMapper, ele está algumas páginas pra frente hahaha)

[quote=Leonardo Gaona]Sergio,

A idéia é que os objetos do domínio sejam apenas focados na lógica de negócio correto?

Pelo que vi nos exemplos do Fowler (simples, ele próprio admite) do ponto de vista do programador, fica uma linguagem muito mais voltada para o negócio, simples de ser entendida (desde que você entenda do domínio, obviamente). No exemplo não se há a menor preocupação sobre como ou onde os dados são persistidos.
[/quote]

correto. é isso.

O data Mapper sempre vai consultar na mesma camada ( camada de recursos ou dados, por isso que ele se chaam 'Data" mapper). O que vc quer dizer é consultar em tecnologia e/ou locais de persistencia diferentes.
Veja que o DataMapper só mappeia. ele não persiste per se ( segundo Fowler ele deveria fazer ambas as coisas, mas podemos desacoplar mais, eu acho) então um objeto de dominio X seria convertido (mpeado) para um conjunto de objetos memento (não necessáriamente é 1-para-1) Y[] . Este conjunto de objetos Y[] seria então enviado para um outro objeto que , ai sim, iria usar a tecnologia de persistência e persistir propriamente. Porque isto ? Para remover o coplamento com a tecnologia de persistencia. O DataMapper sabe “os dados” que precisam ser guardados, ele não sabe onde nem como. O outro objeto que persiste , chamemos de Gate , é o cara que sabe o onde o como, mas não sabe o quê. Se vc lhe dar um conjunto de Y[] que vc inventou (que não veio do mapper) ele persiste na mesma.

O Data mapper não é suficiente para a persistencia, precisa do Gate ( ou seja lá como se chamar). Claro, estou falando apenas em OO puro com as responsabilidades bem divididas. Tecnologia é outra coisa. Vc pode escolher acoplar o data mapper com o gate , obviamente, como fez o Fowler.

.oO(No middlheaven, por exemplo, eu tenho a tecnologia de mapeamento separada da se persistencia. Assim eu posso plugar estratégias de persistencias diferentes para a tecnologia base, mas reaproveitando toda a logica de mapeamento. A forma que eu fiz isso foi criar uma abstração chaamda DataSet e DataRow que converter as instancias de entities em objetos DataRow e DataSet que depois passam para as estratégias de persistencia. Ai cada tecnologia intrepreta os dataset e datarow como achar que deve. para SGDB o data set é uma tabela e o row um linha. Para xml o data ser poder um arquivo e um o row um lainha dentro de uma estrutrua nesse arquivo, etc… cabe à estratégia de persistencia se adaptar ou modelo do que significa um dataset para ela.)

O DataMapper idealmente não cria instancias do domain, ele recebe instancias e as popula. A fábrica de instancia deveria ser um objeto separado. Como esse objeto criado chega no data mapper depende do seu design, não ha uma forma pre-definida. Depende se o datamapper tem controle sobre o ciclo de mapeamento ou ele é controlado por outro objeto que apenas o usa para preencher objetos criados pela fábrica. )

.oO(No middleheaven ele tem os metadados da instancia num objeto e esse objeto tem uma referencia da fábrica. O mecanismo de mapeamento tem acesso aos metadados da instancia e portanto à fábrica. Isto ainda é experimental porque ainda não está resolvido a injeção de outras coisas na instancia -serviços - por exemplo, então as minhas instancias ainda são reflexões dos dados como seria um JPA , por exemplo , mas a ideia é que possam chegar a ser classes de domínio de verdade. Ou seja, por enquanto ele faria o mesmo que o JPA ou o Hibernate mapeando objetos para tabelas, mas com uma camada no meio, onde vc pode definir como partir as entidades em datasets. Por default ele não parte - ainda - e faz o mesmo tipo de mapeamento que o hibernate/jpa fazem.)

Entendi, o caso então é criar uma outra camada abaixo do DataMapper, que pode invocar um DAO (Segundo Fowler, um Gateway) para aí sim se comunicar com a(s) tecnologias de persistência e esse sim retornar para o Mapper um RecordSet que seria utilizado para montar o objeto de domínio.

Interessante que assim fica muito mais fácil de se testar também né? Você pode criar um RecordSet na mão pra validar o Mapper em um teste unitário.

Agora, e em casos onde você não precisaria buscar todos os dados de uma entidade, digamos como um Cliente, sem precisar trazer todos as instâncias de Pedido atreladas a ele, como um relacionamento Lazy do Hibernate? Como fazer?

Métodos de busca diferentes?

[quote=Leonardo Gaona]Entendi, o caso então é criar uma outra camada abaixo do DataMapper, que pode invocar um DAO (Segundo Fowler, um Gateway) para aí sim se comunicar com a(s) tecnologias de persistência e esse sim retornar para o Mapper um RecordSet que seria utilizado para montar o objeto de domínio.

Interessante que assim fica muito mais fácil de se testar também né? Você pode criar um RecordSet na mão pra validar o Mapper em um teste unitário.
[/quote]

Isso não é por acaso. É porque vc desacoplou as coisas. Desacoplar melhora a testabilidade.

[quote]
Agora, e em casos onde você não precisaria buscar todos os dados de uma entidade, digamos como um Cliente, sem precisar trazer todos as instâncias de Pedido atreladas a ele, como um relacionamento Lazy do Hibernate? Como fazer?
Métodos de busca diferentes?[/quote]

Veja que num Domain Model verdadeiro tudo está ligado com tudo a todo o momento. Então o Lazy é feito com truques como proxys e flyweights. Para controlar os proxies o seu domain model precisa existe num container ( um Domain Container) no sentido que na teoria o domain model é solto do mundo, mas na prática ele tem um backup tecnico num mecanismo. Vc pode ter um clientes.getPedidos() que devolve uma lista , mas quando o objeto foi criado essa lista´e apena um proxy. Quando a lista for usada ( por exemplo, iterada) o proxy chaam o mecanismo original para completar o trabalho. O Session do hibernate faz mais ou menos isto, assim como o entitymanager do jpa, mas eles lida com os mementos , mas o mecanismo OO seria o mesmo. Ou seja, no fim as fábricas de objetos e o cara que injeta uns objetos nos outros teria que saber se a leitura é lazy ou não. Mas entenda que isto é artificial e o layz está sendo aplicado aos mementos. No dominio vc sempre poderá fazer clientes.getProdutos().size() porque o objeto já está lá. O fato dele ser um proxy é um detalhe de implementação para poupar recursos. conceptualmente esse proxy não existe.

[quote=sergiotaborda][quote=x@ndy]
Sergio, uma coisa que eu tenho usado já algum tempo e com bastante sucesso é um modelo hibrido.
[/quote]

Outra maneira de dizer “hibrido” é dizer “acoplado”.

Não acredito que o design seja ruim pois meu “Dominio” não é dependente do sistema de persistência. Embora não seja uma tarefa simples, nesse caso não é complicado refatorar o código removendo as anotações e implementar um data mapper. Nunca fiz isso para um sistema inteiro mas mas já implementei para um conjunto de classes, parte do dominio que necessitava ser persistida via XML e em SGDB, dependendo das circunstancias!

Discordo de você que o mundo só usa NoSQL, ao fazer a arquitetura de um novo sistema deve-se avaliar para que o sistema vai ser usado e ai ver o que melhor se aplica. Se vou projetar um ERP para atender as necessidades de uma pequena fabricante de equipamentos para padarias por que vou investir, aumentando os custos, em um projeto que contemple no futuro um banco NoSQL? Mesmo que essa empresa tenha um crescimento exponencial, não sei qual a necessidade do seu negocio daqui a 5, 10 anos! Quem diz que nesse tempo não terá surgido algo no qual o JPA possa ser usado para NoSQL? (Na verdade até já existe algumas coisas). Como posso dizer que esse sistema ainda atenderá as necessidades dele daqui a 5, 10 anos?

Como você mesmo colocou tudo envolve custos, no sistemas que eu projeto isso é um ponto fundamental, embora possa ser pouco, criar um design com data mapper sai mais caro e deve ser justificado e não posso chegar e dizer “por que podemos vir a precisar no futuro!”. Tenho que apresentar dados, e se tenho um 10% de chance de necessitar e isso vai me representar um custo adicional de 5% no valor do projeto, o que é algo razoável, e digamos que o projeto custe agora 1.000.000 (usando seus números) vou economizar 50.000. Com a chance de 10% de que o sistema necesite ser refeito daqui a 5 anos pelo mesmo custo em então meu risco é de 100.000. Se eu aplicar o valor que economizei pelo mesmo periodo com um remuneração média de 1.5% ao mês vou ter ao final R$ 122.160,99 o que é mais que suficiente para que eu não faça o investimento na alteração!

Com certeza a arquitetura do sistema é algo que tem que ser bem planejada e pensada no futuro mas dentro da realidade do presente! XP trata muito bem desse assunto, é bom ler!

Vamos definir o que significa “dependente”. Se vc usa o import da persistencia no dominio é dependente. Se mudar a persistencia implica em editar o codigo fonte do dominio, é dependente.
Mudas as anotações implica em mudar o codigo. então é dependente.

Vc pode argumentar que é “fracamente dependente”. ok. mas é dependente.

:lol: :lol: então o “nunca terei que fazer isso pq nunca fiz antes” não sequer verdadeiro. Vc já fez. Vc já viu que é necessário. Não é imaginário. Não é algo que só acontece nos livros…

Aqui houve uma má interpretação do texto. Eu disse que vc mudaria daqui a 5 ou 10 anos porque “lá, nesse momento” todo o mundo usa NoSQL. Era um argumento no futuro. Não no presente.
É óbvio que não é todo o mundo que usa nosql.

A sua analise é um pouco simplista. Vc está tentando dizer que coisas do futuro não podem ser levadas em linha de conta porque é o aqui e agora é mais barato. Ok. So que estamos falando de riscos. E com riscos essa lógica não se aplica.
O que vc escreveu é equiavalente ao que o porquinho falou quando usou palha. É mais barato. Mas o risco é maior. Logo, ele se ferrou. O porquinho que construiu a casa de pedra gastou mais. Ele investiu. É mais caro, mas o risco é menor. Ele se deu bem.
Se apenas o custo fosse relevante, ninguem vendia seguros. No pior caso vc paga um seguro q nunca via usar. Isso é desperdicio de dinheiro ? Não. É mitigação. O caro agora me salva de um mais caro ainda mais tarde.

O trabalho do arquiteto/designer é diminuir o risco e o custo. Mas o risco tem precedencia. Por quê ? Porque o risco é incontrolável. É aleatório. Então resta apenas mitigar. O desenvolvedor não pode assumir esse risco, nem o arquiteto. E se a gerencia o obriga a assumir esse risco, a gerencia deveria por isso por escrito ( o que nunca acontece). Por isso que eu falei na demissão. Porque quando acontecer, o desenvolvedor que não mitigou o risco que se ferra.
É o trabalho do gerente de projeto e do arquiteto equilibrarem o custo e o risco. Se a decisão de não usar datamapper ou qualquer outra mitigação vem destes dois papeis, ok. Mas se vem de baixo, do desenvolvedor, está errado. Mas para o gerente e o arquiteto equilibrarem o custo e orisco eles precisam saber que o risco existe e qual o seu tamanho e probabilidade. Sobretudo o gerente que não entende sobre como essas coisas aparecem. Ou seja, se foi uma decisão consciente de todo o mundo, blz. Mas se simplesmente foi um atalho para cortar custos , tá errado. E sobretudo porque quando der pau, não é o gerente que vai responder. É quem não implementou o que deveria.

Vc já teve 2 oportunidades para implementar o data mapper. Eu entendi seu lado , não tou dizendo que vc está errado. Mas eu no seu lugar, na segunda vez teria implementado. Da primeira ok, o custo não merece. Mas da segunda, quando eu tenho um caso real que precisa usar , eu colocaria. Ou pelo menos eu alertaria os gerentes e arquietos que deveria ser colocado isso na mesa para discusssão e deixar eles decidirem.

[quote]
Com certeza a arquitetura do sistema é algo que tem que ser bem planejada e pensada no futuro mas dentro da realidade do presente! XP trata muito bem desse assunto, é bom ler![/quote]

Não. Não é na realidade do presente. A arquitetura é três passos á frente do presente. A implementação é que é no presente.
Ou seja, vc pensa no futuro e coloca a implementação que precisa no presente. Mas deixa aberto formas de extender a implementações com outras implementações a seguir. Se for necessário implementar mais coisas, vc pode. Se a sua arquitetura proibe vc de evoluir, ela é uma má arquitetura. Por isso vc ouve falar em postergar decisões. Porque assim que vc fixa a decisão, ela será assim para sempre. Ser arquiteto é a arte de fixar o mínimo de cosias possíveis e mesmo assim ter o sistema que se pretende. E quanto mais longa é a vida do software mais isto é relevante.

[quote=sergiotaborda][quote=x@ndy]

Não acredito que o design seja ruim pois meu “Dominio” não é dependente do sistema de persistência. Embora não seja uma tarefa simples, nesse caso não é complicado refatorar o código removendo as anotações e implementar um data mapper.
[/quote]

Vamos definir o que significa “dependente”. Se vc usa o import da persistencia no dominio é dependente. Se mudar a persistencia implica em editar o codigo fonte do dominio, é dependente.
Mudas as anotações implica em mudar o codigo. então é dependente.
Mudas as anotações implica em mudar o codigo. então é dependente.

Vc pode argumentar que é “fracamente dependente”. ok. mas é dependente.
[/quote]
Ok! O quis dizer é que o sistema tem uma fraca depedencia de modo que o custo de uma refatoração para remove-la é baixo!

[quote=sergiotaborda][quote]
Nunca fiz isso para um sistema inteiro mas mas já implementei para um conjunto de classes, parte do dominio que necessitava ser persistida via XML e em SGDB, dependendo das circunstancias!
[/quote]

:lol: :lol: então o “nunca terei que fazer isso pq nunca fiz antes” não sequer verdadeiro. Vc já fez. Vc já viu que é necessário. Não é imaginário. Não é algo que só acontece nos livros…
[/quote]
Em momento algum eu disse que não é necessário! O que eu estou dizendo é que já mudei parte de uma aplicação hibrida para essa e não foi algo traumático, que deve um custo elevadíssimo!

[quote=sergiotaborda][quote]
Como você mesmo colocou tudo envolve custos, no sistemas que eu projeto isso é um ponto fundamental, embora possa ser pouco, criar um design com data mapper sai mais caro e deve ser justificado e não posso chegar e dizer “por que podemos vir a precisar no futuro!”. Tenho que apresentar dados, e se tenho um 10% de chance de necessitar e isso vai me representar um custo adicional de 5% no valor do projeto, o que é algo razoável, e digamos que o projeto custe agora 1.000.000 (usando seus números) vou economizar 50.000. Com a chance de 10% de que o sistema necesite ser refeito daqui a 5 anos pelo mesmo custo em então meu risco é de 100.000. Se eu aplicar o valor que economizei pelo mesmo periodo com um remuneração média de 1.5% ao mês vou ter ao final R$ 122.160,99 o que é mais que suficiente para que eu não faça o investimento na alteração!
[/quote]

A sua analise é um pouco simplista. Vc está tentando dizer que coisas do futuro não podem ser levadas em linha de conta porque é o aqui e agora é mais barato. Ok. So que estamos falando de riscos. E com riscos essa lógica não se aplica.
O que vc escreveu é equiavalente ao que o porquinho falou quando usou palha. É mais barato. Mas o risco é maior. Logo, ele se ferrou. O porquinho que construiu a casa de pedra gastou mais. Ele investiu. É mais caro, mas o risco é menor. Ele se deu bem.
Se apenas o custo fosse relevante, ninguem vendia seguros. No pior caso vc paga um seguro q nunca via usar. Isso é desperdicio de dinheiro ? Não. É mitigação. O caro agora me salva de um mais caro ainda mais tarde.[/quote]

Discordo de você. A análise aqui é o risco: é tão alto que compensa o custo? Pegando o caso dos três porquinhos, vale mais a pena investir o dinheiro (ou não pagar juros por ele) e fazer uma casa de palha ou gastar o dinheiro na construção de uma casa de pedra quando a possibilidade do lobo mau a aparecer é de 10% daqui a 5 anos? Então temos que pensar! O porquinho ainda vai estar morando nessa casa daqui a 5 anos? E se ele for para a faculdade? E se ele investir esse dinheiro e daqui a 5 anos usar como entrada para fazer uma casa de pedra, com piscina e mais 2 quartos para os filhos? Nesse caso deve-se avaliar se o risco compensa o gasto e claramente não compensa, pois em 5 anos muita coisa pode mudar! Agora vamos dizer que a possibilidade de o lobo aparecer daqui a um ano é de 100% e ele com certeza vai estar morando na casa! Nesse caso o investimento vale a pena! A mesma coisa se aplica ao seguro. Vou comprar um carro hoje para revende-lo daqui a um mês e nesse período ele ficará em uma garagem? O risco de um sinistro é tão alto que compensa o investimento no seguro? Esse pensamento é similar ao que as empresas de seguro fazem! Elas avaliam se o risco compensa o lucro que vão ter. Tanto que o premio para seguro de carro varia conforme a cidade e dependendo do carro (ou do dono) elas nem querem segurar por que o risco é muito alto.

Também discordo. O posso não ter controle sobre o risco, mas posso avaliar a probabilidade de e ele acontecer e seu impacto e com base nisso tomar a decisão de corrigi-lo ou não! O que fazer com um risco com alta probabilidade de acontecer mas com baixíssimo impacto porém com um alto custo para correção? Um exemplo é a torneira que pinga em casa! Outro exemplo, é um risco com baixíssima possibilidade de acontecer mas com alto impacto e custo elevadíssimo, um terremoto em Porto Alegre por exemplo! Nenhuma construção na cidade está preparada na cidade para isso!

Eu acredito que sempre deva-se avaliar os custos e os impactos dos riscos para qualquer decisão!

Bom ai, é outro problema! O projeto deve contemplar a analise de riscos e se o cara aceitou ele deve assinar, se não assinar é melhor ir procurando um emprego por essa empresa é uma bosta!

Concordo!

Nesse caso o custo de alterar todo um sistema que estava em produção não compensava o risco de uma futura alteração pois, como o sistema é hibrido, comporta uma alteração facilmente em outros casos não sei!

[quote=sergiotaborda][quote]
Com certeza a arquitetura do sistema é algo que tem que ser bem planejada e pensada no futuro mas dentro da realidade do presente! XP trata muito bem desse assunto, é bom ler![/quote]

Não. Não é na realidade do presente. A arquitetura é três passos á frente do presente. A implementação é que é no presente.
Ou seja, vc pensa no futuro e coloca a implementação que precisa no presente. Mas deixa aberto formas de extender a implementações com outras implementações a seguir. Se for necessário implementar mais coisas, vc pode. Se a sua arquitetura proibe vc de evoluir, ela é uma má arquitetura. Por isso vc ouve falar em postergar decisões. Porque assim que vc fixa a decisão, ela será assim para sempre. Ser arquiteto é a arte de fixar o mínimo de cosias possíveis e mesmo assim ter o sistema que se pretende. E quanto mais longa é a vida do software mais isto é relevante. [/quote]
Concordo parcialmente, pois acredito que seja necessário estimar a vida do software e tentar utilizar a melhor arquitetura mas acredito que algo que deva ser pesado é a finalidade do sistema, para que ele vai ser usado de modo não criar uma bazuca para matar barata. O próprio Fowler fala sobre isso no livro dele:

Eu uso DDD e NoSQL e não vejo como as duas coisas podem ser exclusivas. Tb não vejo qq impedimento para usar DDD + NoSQL + Relacional.

Mas qual seria um exemplo de uso de Relacional + NoSQL André?

Persistir os IDs em um banco relacional e outros dados no NoSQL?

[quote=Leonardo Gaona]Mas qual seria um exemplo de uso de Relacional + NoSQL André?

[/quote]

Vc quer saber as aplicações de cada um deles, certo?

Bem didático…

[quote=Leonardo Gaona]Mas qual seria um exemplo de uso de Relacional + NoSQL André?

Persistir os IDs em um banco relacional e outros dados no NoSQL?[/quote]

NoSQL == Not only SQL

(Em outras palavras: use a ferramenta certa para a coisa certa).

[]'s

[quote=Leonardo Gaona]Mas qual seria um exemplo de uso de Relacional + NoSQL André?

Persistir os IDs em um banco relacional e outros dados no NoSQL?[/quote]

Não! É uma arquitetura Hibrida! Você persiste parte dos dados em um modelo relacional e outra parte utilizando NoSQL. É o que o Martin Fowler chama de persistência poliglota, ou seja você analisa o sistema e vê o que é mais indicado ser persistido em um banco de dados relacional e o que é mais indicado persistir em um banco de dados NoSQL.