O que usar no lugar de VOs?

[quote=emerleite]Sérgio, dizer se getVersion descaracteriza DDD ta beirando o absurdo vai?
[/quote]

Entenda getVersion como um exemplo de método/atributo de infra/estrutura.

Eu acredito que os conceitos são para ser compreendidos ao pé da letra. Só depois de o compreeder ao pé da letra vc se pode dar ao luxo de não os seguir. Só depois de os entender o trade-off será realmente um trade ( uma troca) e não apenas uma escolha pelo mais simples, mais comum … ou mais gambiarra…
Apenas com um entendimento consistente pode haver um design coerente.

Se eu chamar de DDD qualquer coisa que tenha entidades , serviços , repositorios e VO , e não seguir ao pé da letra vou acabar concluindo que EJB é DDD. :shock:

humm… foi exactamente ao não usar Hibernate/JPA que precisei do getVersion, getKey e outros companheiros deles…

[quote]Poderiamos fazer tudo com XML de mapeamento ou SQL dentro do DAO (ARGH), controlar o lock dos registros no braço, em fim, tudo como era antes. Também não acho o melhor dos mundos a forma como é feita hoje.

Agora te pergunto: tem alguma “melhor maneira possível” além dessa? Eu sinceramente não conheço. E outra: Essas coisas tornam DDD um anti-pattern quando usado com EJB como você falou?[/quote]

Maneira possivel ? Claro. O povo não gostou do EJB 2 , apareceu o Spring. O Spring matou a pau ? Toma EJB 3. Não gostou do DAO, apareceu o hibernate. Não gostou do System.out.println() apareceu o Log4J. Existe sempre uma maneira melhor

[explicação longa]

Eu considero que o melhor seria assim:

  1. Não reimplementar logicas de dominio.
  2. Não reimplementar logicas de persistencia
  3. Não reimplementar logicas de apresentação.

Com logicas de dominio não me refiro a logicas de negocio. Por exemplo, Pedido tem itens. Pertence a um cliente. O cliente é uma pessoa. A pessoa é um individuo ou uma empresa. Isso é dominio. Negocio é : se a pessoa está na faixa etária X recebe Y desconto. Se hoje é dia Z os produtos H são mais baratos., etc…

Persistir no banco, em memoria, distribuido, com cache ou sem cache, como HTTP ou sem. Prevayler, SQL Server , Postgres, XML , Banco orientado a objetos … Em ambiente de teste , homologação, produção … em qualquer situação , ocasião e tempo o meu sistema não depender de saber onde estão os dados.

Não ter que implementar mecanismos de procura de dados, filtro, cadastro, consistencia. Seja Swing, HTML, Ajax … Seja distribuido, ou standalone … Todo esse trabalho burocrático é um saco.

Existe sempre uma maneira melhor.
A minha maneira melhor pode não ser a sua. Mas se conseguir me livrar dos 3 pontos acima e poder me concentrar no que o cliente quer - a logica de negocio - já vou achar bom.

Eu entendo o DDD como uma forma de obter o 1. Para isso o dominio tem que ser completamente desprovido de ligações com a infra, porque so dessa forma vou poder reaproveitá-lo em outros sistemas. Pense o tempo que pouparia se existisse um framework de dominio como carrinhos de compras, clientes, produtos, notas fiscais , etc… tudo pronto. VC pega, ajusta e voilá. Isso só é psosivel se as classes forem completamente independentes de frameworks como Hibernate ou tecnologias como JDBC.

O nivel de trabalho, design e esforço necessários para alcançar este ponto são imensos. Por outro lado ha que analizar tecnologias que dão suporte a tudo isto. E mesmo quando vc tenha o framework martelinho de ouro ele ainda tem que ser compativel com padrões : ou então ele tem que ser super bom e virar o padrão.

[/explicação longa]

Essa é a busca da arquitetura perfeita Sérgio… mas acho que alguns pontos devem ser considerados:

  • Quanto de esforço ja foi feito em projetos para independência de frameworks, reaproveitamento massivo de front-ends, DAOs ultra-power-megalomanícos-genericos ?

  • Quanto destes esforços já vimos em tantos projetos onde o sistema não vai deixar de ser Hibernate para ser iBatis, trocar Pico pelo Spring ou trocar a interface web por GUIs Swing pelo menos nos próximos 100 anos ?

Acredito que a arquitetura ideal não seja a mais “independente”, justamente pq muitos projetos simplesmente não mudam sua infraestrutura técnica… o mais comum é que seja alterado varias vezes o domínio do negócio. Vejo que responder rápido a essas mudanças (aqui é onde o DDD deita e rola), tem prioridade do que alterar a “API de persistencia”.

Já vi muitos projetos onde o excesso de zelo com os padrões, tornam o mesmo incompatível com o número de horas para realizar tarefas simples, contudo, depois de anos, a arquitetura inicial permanece inalterada.

Isto não é apologia contra padrões, tampouco estou anulando alguma coisa de seu post anterior, mas acho prudente avaliar o que citei antes de optar por uma arquitetura “extrema”.

[quote=Lezinho]Essa é a busca da arquitetura perfeita Sérgio… mas acho que alguns pontos devem ser considerados:

  • Quanto de esforço ja foi feito em projetos para independência de frameworks, reaproveitamento massivo de front-ends, DAOs ultra-power-megalomanícos-genericos ?
    [/quote]

boa pergunta. quanto foi ? não encontrei até agora nenhum framework nessas condições. (com exceção tlv do naked objects … mas com algumas limitações)

Essa não é a minha preocupação. Se o cliente não quer mudar o problema é dele. A minha preocupação é poder criar rápidamente aplicações para qualquer cliente em qualquer tipo de arquitetura. Poder mudar rápidamente quando o cliente quiser mudar. Básicamente é não perder tempo com requistos não funcionais. É reutilização do ponto de vista da fabrica de software e não do cliente em si. É como ter máquinas e tooling* e não como vender um produto tudo-em-um. Acontece que em informática as ferramentas e o produto final se confundem.

(*tooling, para quem não sabe é a ter várias peças que montadas numa mesma máquina permitem a máquina exercer tarefas diferentes)

[quote=sergiotaborda][quote]

  • Quanto destes esforços já vimos em tantos projetos onde o sistema não vai deixar de ser Hibernate para ser iBatis, trocar Pico pelo Spring ou trocar a interface web por GUIs Swing pelo menos nos próximos 100 anos ?
    [/quote]

Essa não é a minha preocupação. Se o cliente não quer mudar o problema é dele …[/quote]
Também é problema dele pagar horas demasiadas pra você fazer BDUF e ainda demorar mais pra entregar os releases.

Me explica como que você tem feito isso porque sempre temos que fazer mapeamentos seja por annotations, XML ou então colocando o SQL no DAO se você preferir. Não sei como que você consegue não gastar tempo com isso. Só se você estiver falando de Rails com ActiveRecord, ou algo parecido. Já em Java, desconheço.

Fábricas de Software são uma idéia falida. Faça uma busca aqui no forum sobre o assunto. Falando em reutilização, acho pouco provável você reaproveitar da forma que você está falando. Por acaso você acha que vai aproveitar o Domain Model de um projeto de um cliente em outro projeto de outro cliente só porque é meio parecido? Você vai ter é muita dor de cabeça isso sim. Até se você fizer uma DSL para seu cliente, não vejo muito como você reaproveita-la para outro cliente. Acho que vai conseguir é usar a experiência que teve com o ramo de negócio, mas cada caso é um caso.

Eu já acho que pode. O problema é que até aqui não tem sido viável. Talvez não role de usar o mesmo domain, mas você poderia especializá-lo ou criar outro que dependesse e encapsulasse(é assim que escreve?) o domain existente, adicionando então as características específicas necessárias.

Ao meu ver, o ideal era que fosse assim. Isso não quer dizer que seja fácil fazer assim.

Com java vc consegue muitas coisas. Concerteza não o fiz com um framework de prateleira. Tive que criar o meu. Sim, usa metadados ( já disse que não tenho nada contra), mas usa uma fabrica de metadados para possam ser lidos de onde for necessário: pode até ler do banco se quiser. E não usa entidades, usa HashDTO.
O meu problema agora é como encaixar isso com POJO.

Vc se prendeu demasiado com as palavras. Me referia ao ponto de vista de quem cria o sowftare, e não de quem o usa. Lá porque o cara quer ligação com oracle isso não significa que não posso reutilizar os componentes de um projeto antigo. E tb não estou dizendo que vai impleemntar todas as possibilidades de uma vez. O que estou dizendo é que a arquitetura e o design tem que ser tal que se eu precisar eu possa fazer.

Eu não posso usar o modelo de dominio do cliente X no Y, mas eu posso extender o dominio do X do A e o Y do A e aperfeiçoar o A quando necessário. Se vc reparar com atenção muitos dos problemas se devem a desconhecimento do dominio. Aquele que o cliente lhe passou não é real é o que ele usa. Uma versão simplificada. Na hora de integrar isso com outra empresa ou melhorar o sistema, não dá certo. E ai vem a gambiarra. Se vc tem um modelo de dominio prévio vc pode detectar os erros mais cedo: não deixando que se perca tempo programando algo que não irá funcionar.

[quote=sergiotaborda][quote=emerleite]

Me explica como que você tem feito isso porque sempre temos que fazer mapeamentos seja por annotations, XML ou então colocando o SQL no DAO se você preferir. Não sei como que você consegue não gastar tempo com isso. Só se você estiver falando de Rails com ActiveRecord, ou algo parecido. Já em Java, desconheço.
[/quote]

Com java vc consegue muitas coisas. Concerteza não o fiz com um framework de prateleira. Tive que criar o meu. Sim, usa metadados ( já disse que não tenho nada contra), mas usa uma fabrica de metadados para possam ser lidos de onde for necessário: pode até ler do banco se quiser. E não usa entidades, usa HashDTO.
O meu problema agora é como encaixar isso com POJO.
[/quote]
Ai que está o problema. Eu acho que Java tem limitações por concepção que dificultam muito o fazer uma coisa dessas. Vai ter que criar um monte de gambiarras pra “tentar” chegar aonde você quer. Tem certeza que você não está criando um frankstein?

Não entendi. Pode explicar melhor? Você vai reaproveitar que componentes? você tinha dito reaproveitar o Domain Model.

Você não disse que vai implementar tudo de uma vez mas disse que iria fazer um Design sem ao menos uma idéia se o cliente vai precisar da flexibilidade que você estava criando. Isso é BDUF sim.

Sinceramente eu tenho uma opinião bem diferente. Eu penso no domínio como algo especializado para uma empresa, que foi desenvolvido conversando com os Analistas de Negócio e o Product Owner. Quando for pensar no domínio de outra empresa o máximo que eu usaria é a experiência anterior para direcionar melhor, ganhar agilidade e tentar acertar mais rápido.

@thiago
Cara, como eu disse ao Sérgio, eu acho que no caso de 2 clientes que o ramo de atuação é o mesmo, aproveitar a experiência e dar uma olhada no Domínio feito para o primeiro cliente ajuda, mas dai a reaproveitar o Domínio sinceramente acredito que vai dar mais dor de cabeça que ajudar.

Realmente, entendo seu ponto de vista. Essa idéia de reaproveitar o domain nunca vi na prática e também não vejo no java uma forma agradável de se fazer isso. E de fato, reaproveitar o domínio é uma dor de cabeça. Mas o que acho é que isso não deveria ser uma dor de cabeça.

Acho estranho discutir DDD como uma ferramenta de modelagem somente. Acho que um benefíco que pode ser gerado por DDD a médio prazo é ‘como modelar um domínio que possa ser reutilizável sem gerar dor de cabeça’. :slight_smile:

O modelo é apenas um dos componentes. Veja os posts mais atrás.

Entenda que não me interessa se o cliente vai precisar. Me interessa se eu vou precisar. E eu tenho uma ideia do que eu preciso ( os 3 pontos que enumerei antes). O exemplo do DAO acho que é mais facil vc entender.
O design menciona um DAO. A arquitetura e tudo o resto está constuido em cima. A única peça que tenho que alterar para mudar Oracle para SQL Server ou JGroups é apenas o DAO. Quando o cliente1 pedir um sistema
com SQL Server eu vou lá e implemento o DAO. Ai ele fica guardado. Quando o cliente2 pedir um sistema diferente com o SQLServer eu vou lá e uso o DAO que já tinha; poupando o tempo de construção de um DAO.
Não é o cliente que vai mudar de banco, sou eu. Se N clientes quiserem N bancos diferentes tenho que implementar N DAO mas se N clientes quiserem M bancos ( M < N) só preciso implementar M. E M tende a ser pequeno ( <10) enquanto N pode ser arbitráriamente grande. (Obviamente estamos falando de um DAO genérico que funciona para qualquer entidade.) Isto não é dificil de conseguir. Veja o exemplo do Hibernate.
O ponto é que o hibernate só funciona via JDBC. O objetivo é funcionar com qq tecnologia necessária. Mas "funcionar" não significa que vc sai implementando para todas as tencologias.
Enfim, não é um trabalho tão arduo quanto parece.

Isso tudo que você falou sobre a fonte de dados se resume de forma simples em você criar uma interface usando o padrão Repository [Fowler] e implementa-lo da forma que achar melhor e por trás dos panos pode persistir onde quiser. Por termos demanda muito grande de aplicações que persistem dados num SGBD o Hibernate foca nisso, mas nada impede que você tenha uma implementação do Repository que salve em arquivo XML, VSAM ou [coloque o nome do que você quiser aqui].

E lembrando de DDD, Repository é mencionado como algo pertencente ao Domain Model e usando ele, mesmo com EJB3, não estará aplicando um anti-pattern.

[quote=sergiotaborda]2)Por outro lado usar V[D{T}]O é o que se faz em tenologias modernas como EJB 3 e em qualquer framework que se destine a ser generico. A persistencia não se importa com o comportamento, apenas com os dados e sempre, sempre, ela usará V[D{T}]O porque ela é "forçada" a seguir o padrão Memento.
3) Desafiar a separação entre V[D{T}]O e Serviços não faz sentido nem em DDD nem em nenhum modelo de dominio que se preze. Nem EJB faz isso. O modelo anémico é realmente o que é usado na prática e não ha como ser de outra forma quando queremos usar tencologias de mercado. Portanto não ha como se livrar do V[D{T}]O se queremos ser práticos e menos puristas.
3.1) se quiser ser purista pode, mas em sistemas limitados, não distribuidos. Em sistemas distribuidos a pureza é um empecilho e isso rápidamente significa que se não ha purismo, não ha porque eliminar os V[D{T}]O.
[/quote]

DDD fala sobre integração, a ultima parte do livro se dedica exclusivamente a este topico. E o que vale pra integracao de dois sistemas distribuidos vale também quando um deles é a apresentacao. A regra geral é, não distribua seus objetos.

Quando vc diz que sistema distribuido é problema com DDD nao faz sentido pq a integracao ocorrre fora do dominio, e este não distribui seus objetos!

Acho até interessante a ideia de frameworks que fazem bind direto dominio<->apresentacao mas se envolvermos remoting a situacao muda, pq entao estaremos distribuindo os objetos.

Em relacao a persistencia discordo totalmente, acho superada qualquer necessidade de DTO.

Sim. De forma simples, se resume a isso. Mas de forma não resumida não é tão simples assim.

[quote=cmoscoso][quote=sergiotaborda]2)Por outro lado usar V[D{T}]O é o que se faz em tenologias modernas como EJB 3 e em qualquer framework que se destine a ser generico. A persistencia não se importa com o comportamento, apenas com os dados e sempre, sempre, ela usará V[D{T}]O porque ela é "forçada" a seguir o padrão Memento.
3) Desafiar a separação entre V[D{T}]O e Serviços não faz sentido nem em DDD nem em nenhum modelo de dominio que se preze. Nem EJB faz isso. O modelo anémico é realmente o que é usado na prática e não ha como ser de outra forma quando queremos usar tencologias de mercado. Portanto não ha como se livrar do V[D{T}]O se queremos ser práticos e menos puristas.
3.1) se quiser ser purista pode, mas em sistemas limitados, não distribuidos. Em sistemas distribuidos a pureza é um empecilho e isso rápidamente significa que se não ha purismo, não ha porque eliminar os V[D{T}]O.
[/quote]

DDD fala sobre integração, a ultima parte do livro se dedica exclusivamente a este topico. E o que vale pra integracao de dois sistemas distribuidos vale também quando um deles é a apresentacao. A regra geral é, não distribua seus objetos.

Quando vc diz que sistema distribuido é problema com DDD nao faz sentido pq a integracao ocorrre fora do dominio, e este não distribui seus objetos!
[/quote]

Na teoria isso é muito bonito. Num sistema web isso é baba. Num sistema standalone tb.
Agora, experimente não distribuir o dominio num sistema swing cliente-servidor. Melhor, tente fazer isso num sistema sometimes-connected.

Hehe.
Isso acontece porque o Swing é um framework extremamente invasivo e sua arquitetura é anti-MVC. O EJB 2.x é fichinha perto do que o Swing te força a fazer. Os entusiastas do Swing dizem que ele é puro MVC, mas quem já trabalhou de verdade com ele e já deu uma olhadinha no código-fonte sabe que não é. Para separar o Swing de qualquer outra coisa são necessárias dezenas de AFLs.

  • AFL = Another Fucking Layer

[quote=victorwss][quote=sergiotaborda]
Na teoria isso é muito bonito. Num sistema web isso é baba. Num sistema standalone tb.
Agora, experimente não distribuir o dominio num sistema swing cliente-servidor. Melhor, tente fazer isso num sistema sometimes-connected.
[/quote]

Hehe.
Isso acontece porque o Swing é um framework extremamente invasivo e sua arquitetura é anti-MVC. O EJB 2.x é fichinha perto do que o Swing te força a fazer. Os entusiastas do Swing dizem que ele é puro MVC, mas quem já trabalhou de verdade com ele e já deu uma olhadinha no código-fonte sabe que não é. Para separar o Swing de qualquer outra coisa são necessárias dezenas de AFLs.

[/quote]

Bom, eu já usei o swing muito e continuo achando que MVC. Alias o verdadeiro MVC (não essa coisa que se usa em web) já existe uma camada para a separação : os models. Se vc usar como mandam as regras é simples e eficaz.
Agora, se anda por ai usando o DefaultTableModel mechendo com arrays e coisas assim, ai merece mesmo sofrer :twisted:
E depois alguem vem comparar Swing com SWT. Ah! quando é que se vão dar conta que SWT é um comcorrente do AWT ? O verdadeiro concorrente do Swing é o JFaces, que segue a mesma estrutura MVC.

Eu acho o swing muito util. O problema de programar desktop não é o swing, é o cache. As telas ricas demandam muita comunicação continua com o repositorio e se ele está remoto a performance é muito ruim. Por outro lado o cache é distribuido e dinamico. Isso que complica demais.

[quote=victorwss]
Isso acontece porque o Swing é um framework extremamente invasivo e sua arquitetura é anti-MVC.[/quote]

Baseado em que “visão” vc afirma isso?

Quanto ao swing:

Se o seu uso de swing se limita a utilizar alguns componentes crus e setar umas propriedades. Sorria feliz e comemore, você está em um mar de rosas.

Agora, se você precisa personalizar TableModels, CellEditors, CellRenderers, ComboBoxModels, ListCellRenderer, aí a coisa fica BEM mais complicada. Todas estas coisas são fortemente acoplados a JComponents, de forma que reutilizar tais códigos em um ambiente que não tenha nada de swing é praticamente impossível, e é nestes pontos que as suas view vai se integrar com suas models e controllers. Então a saída seria AFLs.

Outra coisa perversa são os listeners. Eles estão fortemente acoplados ao AWT. Não é apenas um simples acoplamento de ser apenas algumas dependências para compilar (se fosse só isso, ainda estaria tudo bem) e sim que para que eles funcione corretamente é necessário se ter toda a estrutura do AWT por de baixo. Quanto ao MVC, é necessário que a sua model e/ou controller seja um listener para receber eventos do AWT. Como separá-los? AFL!
Mas por outro lado, quanto aos listeners, acho difícil imaginar uma outra arquitetura que pudesse ser melhor que essa (imaginar piores é fácil :twisted: ).

Ah, e alguém já tentou mudar a cor do texto em uma combo box disabled? Não existe nenhum setter ou getter para isso nem na ComboBox, na ComboBoxUI e nem no ComboBoxEditor. Ano passado eu tive que dar um jeito de fazer isso e está hardcoded nas profundezas do swing não lembro onde. Se quiserem posso até procurar. No final consegui fazer uma maluquice para resolver isso, mas foi difícil.