Estou estudando o livro sobre DDD e estou achando muito interessante os conceitos apresentados, mas estou com dificuldades para entender algumas coisas, como pode ser implementada a paginação de resultados de serviços que exigem um processamento de muitas instancias de classes? e ordenação?
Como vocês tem implementado estes dois conceitos tanto para a tela como para o domínio?
Os métodos dos repositórios podem receber parâmetros indicando o offset, o máximo e talvez até a ordenação.
Se pensarmos no repositório como uma implementação de collections, podemos concluir que é de responsabilidade dele, o repositório, cuidar da organização, retorno e ciclo de vida dos dados.
A implementação prática depende muito da estratégia da sua paginação. Mas se for 1 query para cada página por exemplo, supondo que estamos falando de DBs relacionais, eu repassaria esses parâmetros para os DAOs. Mas há casos e mais casos. =)
T
Thiago_Senna
Eu já acho que ordenação e paginação não é problema do repositório. Depois de muito quebrar a cabeça decidi mandar o DAO e o Repositório pra cucuia. Como opção, comecei criando as queries usando session diretamente. Depois refatorei, encapsulando as queries dentro de query objects.
Acho muito ruim implementar paginacao usando DAO ou Repositório pois eu preciso de no mínimo dois métodos:
Repositorio.findAll(int first, int count);
Repositorio.findAllCount();
Outro problema que tive é que usando o banco de dados hsqdb (pelo menos) eu não consigo utilizar a mesma query para fazer a busca e o count. Isso pq quando adiciona ordenação na minha criteria o count simplesmente quebra. Ai, lá vai gambi pra organizar tudinho.
Estou estudando o livro sobre DDD e estou achando muito interessante os conceitos apresentados, mas estou com dificuldades para entender algumas coisas, como pode ser implementada a paginação de resultados de serviços que exigem um processamento de muitas instancias de classes? e ordenação?
Como vocês tem implementado estes dois conceitos tanto para a tela como para o domínio?
Obrigado.
Eu uso um objeto de paginação (algo nas linhas disto) mas o segredo aqui é objeto Query que não é um conjunto de objetos mas um Fastlane para refazer a pesquisa várias vezes.
Moral da historia, vc resolve com bom OO. DDD não lhe vai ensinar isso.
F
feliperod
Thiago Senna:
Eu já acho que ordenação e paginação não é problema do repositório. Depois de muito quebrar a cabeça decidi mandar o DAO e o Repositório pra cucuia. Como opção, comecei criando as queries usando session diretamente. Depois refatorei, encapsulando as queries dentro de query objects.
Acho muito ruim implementar paginacao usando DAO ou Repositório pois eu preciso de no mínimo dois métodos:
Repositorio.findAll(int first, int count);
Repositorio.findAllCount();
Outro problema que tive é que usando o banco de dados hsqdb (pelo menos) eu não consigo utilizar a mesma query para fazer a busca e o count. Isso pq quando adiciona ordenação na minha criteria o count simplesmente quebra. Ai, lá vai gambi pra organizar tudinho.
enfim… resumindo:
Ótimo, agora pega o seu objeto Query e chama ele de dentro do repository. \o/
A implementação não precisa ficar no repository. Porém se você excluir o repository e começar a criar métodos alternativos para manipular os dados, estará ferindo os principios do DDD. Como o Sergio falou, você resolve isso com bom OO e o DDD vai funcionar normalmente como em qualquer outro caso.
T
Thiago_Senna
Pra que?
Sim, de fato!
Mas que dados alternativos são esses que só seria interessante manipular dentro de um repositório?
Pode ser, mas dá muito trabalho. Usar query object já é bem elgante se falando de OO. Quanto a DDD, manter os repositórios se transformou em uma guerra contra os frameworks que utilizo.
F
feliperod
Pra que?
Bom, os benefícios do uso de repositório são vários. O Eric Evans cita que sem eles o risco é que o domain fique “limboso” (de limbo mesmo).
Entendo que o caso não seja muito óbvio se levarmos em consideração somente o caso da paginação, mas estamos falando de um sistema maior, certo?
Mas que dados alternativos são esses que só seria interessante manipular dentro de um repositório?
Não dados alternativos, eu disse métodos alternativos ou formas alternativas. Por exemplo obter os dados por fora, sem o repositorio em algumas vezes e em outras obter através do repositorio. O ponto de acesso a dados deve ser único. Para isso servem os repositórios.
Pode ser, mas dá muito trabalho. Usar query object já é bem elgante se falando de OO. Quanto a DDD, manter os repositórios se transformou em uma guerra contra os frameworks que utilizo.
Bom, dois pontos… primeiro, QueryObject é uma solução inteligente de OO. Pode ser utilizada em conjunto com os repositórios.
Quanto ao caso dos frameworks, eu concordo que às vezes é difícil de manter. Em casos como o Rails/Grails por exemplo, é uma opção ignorar o uso de repositórios, mas aproveitar outros conceitos do DDD. Eu faço isso frequentemente.
Para modelos mais complexos ou maiores, mesmo com esses frameworks, eu aconselho o uso dos repositorios. Talvez a dificuldade de uso possa se revelar uma má separação das camadas? Talvez. Eu investigaria.
T
Thiago_Senna
Humm, acredito que o tamanho do projeto não é o problema. A quantidade e a qualidade dos desenvolvedores poderiam afetar se a arquitetura será mais “burocrática” ou mais “froxa”.
Então, no meu caso afroxei. No caso de obter os dados por fora será sempre através de QueryObjects. Uma operação mais complexa envolvendo mais entidades coloca-se em um Service. Outra operações como load, save e remove tenho abstraído nos próprios componentes de UI.
Eu tenho buscado dia a dia uma produtividade similar a Rails e Grails, no entanto, utilizando Java, Spring, Hibernate e Wicket. Num cenário como este manter o repositório se tornou uma guerra contra esses frameworks, mesmo. Isso se agravou principalmente por causa do Wicket, já que não é tão complicado criar componentes de UI um pouco mais espertos.
Sinceramente… tenho achado que em geral, nós desenvolvedores java, criamos camadas demais. Outros frameworks e linguagens tem se saído tão bem com arquiteturas tão mais simples. Então, por enquanto, vou tentar seguir esta receita. O mínimo de camadas possíveis. Caso necessário, no decorrer do projeto, refatoramos para algo mais “defensivo”.
Na medida do possível, a idéia é manter e aplicar as boas idéias do DDD, só que inicialmente sem o repositório, que é onde a briga contra os frameworks é mais intensa.
S
sergiotaborda
Thiago Senna:
Pode ser, mas dá muito trabalho. Usar query object já é bem elgante se falando de OO. Quanto a DDD, manter os repositórios se transformou em uma guerra contra os frameworks que utilizo.
QueryObject é um padrão , mas como todos os padrões pode ser usado da forma errada. QueryObject precisa ser usado conjuntamente com um Interpreter. No seu caso o objeto é QO e Interpreter ao mesmo tempo :shock: portanto violando o
principio de responsabilidade e portanto não sendo OO elegante ( esquece elegante, não é bom OO para começo de conversa)
O problema de não usar QueryObject conjuntamente (cooperação) com um outro objeto - neste caso o repositorio que faria o papel
de interpreter - é o acoplamento. Com um QO desassoiado do repistorio vc pode ter muito mais flexibilidade porque pode mandar o mesmo QO para reposiotorios com implementações diferentes (um real e um de teste, por exemplo).
F
feliperod
Leal Thiago, parece que estamos entrando em consenso agora. =)
Thiago Senna:
Eu tenho buscado dia a dia uma produtividade similar a Rails e Grails, no entanto, utilizando Java, Spring, Hibernate e Wicket. Num cenário como este manter o repositório se tornou uma guerra contra esses frameworks, mesmo. Isso se agravou principalmente por causa do Wicket, já que não é tão complicado criar componentes de UI um pouco mais espertos.
Só reparei que talvez sua dificuldade para usar os respositorios esteja exatamente na aplicaçào do smart-UI ou componentes UI mais espertos. Não digo que é certo ou errado, mas muitos, inclusive o Eric Evans menciona no livro, o pattern Smart-UI exclui mutuamente o uso do MDD, permitindo o uso das outras pŕaticas do DDD.
Esse é o espírito. =)
T
Thiago_Senna
Entendo, entendo. Mas em minha opinião este esforço não tem valido a pena. Nada contra em implementar um bom OO, mas a real é que no fim, se vc juntar tudo que você implementou para fazer tudo ficar bonitinho praticamente vira um framework novo. Não é a toa que você está desenvolvendo o MiddleHeaven, certo?
Infelizmente aplicar patterns, OO, separação de camadas e essas coisas de forma bonitinha é sofrido demais. Principalmente hoje dependendo de qual framework vc está adotando.
Humm… deixe eu levantar uma questão interessante baseado em uma colação que você fez:
Hoje, utilizando wicket, ainda posso colocar o interpreter fora do repositorio. Eu poderia numa boa criar um componente de UI que fizesse a interpretação do QueryObject. Melhor fazer isso do que criar o componente de UI, que chama o repositório e que por fim, chama o QueryObject. IMHO é muita delegação. A maioria dos projetos não precisam ser defensivos a este ponto, acho. E vocês, o que acham?
T
Thiago_Senna
feliperod:
Leal Thiago, parece que estamos entrando em consenso agora. =)
Thiago Senna:
Eu tenho buscado dia a dia uma produtividade similar a Rails e Grails, no entanto, utilizando Java, Spring, Hibernate e Wicket. Num cenário como este manter o repositório se tornou uma guerra contra esses frameworks, mesmo. Isso se agravou principalmente por causa do Wicket, já que não é tão complicado criar componentes de UI um pouco mais espertos.
Só reparei que talvez sua dificuldade para usar os respositorios esteja exatamente na aplicaçào do smart-UI ou componentes UI mais espertos. Não digo que é certo ou errado, mas muitos, inclusive o Eric Evans menciona no livro, o pattern Smart-UI exclui mutuamente o uso do MDD, permitindo o uso das outras pŕaticas do DDD.
Humm, Smart-UI? Não li este capítulo! Valeu pela dica, Filipe.
Valeu, acabei de dar uma lida em ambos para comentar aqui. (depois leio com mais calma)
Curti os artigos. A única parte assustadora é que de cara eles citam o Smart-UI como um anti-pattern. Com certeza, se considerar que o Smart-UI faz selects na base, sem dúvida nenhuma a lista de desvantagens será grande.
Já no caso como estou implementando tá rolando algo um pouco diferente, talvez, um Semi-Smart-UI (rsrs). A lógica de negócio e queries ainda continuarão (ou pelo meno devem continuar) no domínio.
Quero também destacar este trecho:
Eu tenho tomado este cuidado. Bom saber que mesmo ousando na camada de UI é possível se falar em DDD.
F
feliperod
Thiago Senna:
Valeu, acabei de dar uma lida em ambos para comentar aqui. (depois leio com mais calma)
Curti os artigos. A única parte assustadora é que de cara eles citam o Smart-UI como um anti-pattern. Com certeza, se considerar que o Smart-UI faz selects na base, sem dúvida nenhuma a lista de desvantagens será grande.
Já no caso como estou implementando tá rolando algo um pouco diferente, talvez, um Semi-Smart-UI (rsrs). A lógica de negócio e queries ainda continuarão (ou pelo meno devem continuar) no domínio.
Quero também destacar este trecho:
Eu tenho tomado este cuidado. Bom saber que mesmo ousando na camada de UI é possível se falar em DDD.
Na verdade o Smart-UI é um anti-pattern no contexto do Model Driven Development. Se você não se propor a usar o MDD, então o Smart-UI não é um Anti-Pattern.
O DDD é um processo de práticas, onde uma complementa a outra. Se usarmos várias práticas do DDD mas não usarmos o MDD, estamos também fazendo DDD?
Eu acho que sim.
Não gosto de pensar que quem faz DDD é o bom e quem não faz é o ruim. Gosto de pensar que o DDD nos sugere uma série de práticas por um motivo. Essas práticas se justificam pelos benefícios que elas apresentam. Então eu gosto de pensar: Tal projeto está usufruindo dos benefícios totais. Tal projeto está usufruindo de parte dos benefícios, pois não aplica todas as práticas. Tais projetos não se beneficiam por que não aplicam boas práticas.
Assim, acho mais justo. No seu caso, você deve estar se beneficiando pelo menos de algumas práticas. Talvez até possa evoluir para ter ainda mais benefícios. Talvez nem precise. Cabe a você julgar isso. =)
S
sergiotaborda
Entendo, entendo. Mas em minha opinião este esforço não tem valido a pena.
Bom, então só posso concluir que vc não faz testes automáiticos no seu software… porque só para facilitar os testes já é uma benção para mim.
Fazer bom OO é mais facil que fazer mau OO. Eu sei que é dificil de acreditar, mas é verdade. Vc codifica menos e com mais gosto.
O MiddleHEaven é por causa do principio DRY , porque ficar implementando a mesma coisa 300 vezes ? e já que vai fazer , faz direito ( easy said than done)
Hum… provavelmente porque usa os framework errados.Escolher frameworks com flexibilidade suficiente não é simples.
Hoje, utilizando wicket, ainda posso colocar o interpreter fora do repositorio. Eu poderia numa boa criar um componente de UI que fizesse a interpretação do QueryObject. Melhor fazer isso do que criar o componente de UI, que chama o repositório e que por fim, chama o QueryObject. IMHO é muita delegação. A maioria dos projetos não precisam ser defensivos a este ponto, acho. E vocês, o que acham?
Para mim QO é um objeto de contexto , ele viaja entre camadas , mas não desde da UI. Essa de fazer um interpretador na UI não entendi. O interpretador deveria estar perto do repositorio / hibernate / entitymanger e não longe na UI.
Em vb usava smart-UI e sempre achei acoplado demais. Por isso que gosto de java e OO porque vc pode (deve?) não usar smart-UI.
smart-UI para mim é usar Jquery fazendo tabs e menus dinamicos e até ajax… mas as logicas de manipulação, qeury, etc é tudo no codigo back-end por causa da reusabilidade.
E
euprogramador
Pessoal, que bom que o post tenha dado esta discursão tão produtiva para a comunidade.
realmente é bom ter várias cabeças pensando junto, estou implementando uma abordagem de Fluent interfaces para o meu Repositorio onde tenho métodos que fazem chamada da seguinte forma:
a linha 1 me retorna uma lista de todos os usuários com o nome carlos alberto que estejam ativos e ordenado por nome na primeira pagina e retorna 40 registros.
a linha 2 faz a mesma coisa mas me retorna a contagem.
caso tenha um critério mais especifico implemento um método dentro do repositorio especificamente para atender a demanda do mesmo.
assim o cliente do repositorio pode selecionar de forma livre os dados que deseja e ainda implementar a paginação e ordenamento.
T
Thiago_Senna
Crio os testes automatizados numa boa. Conclusão precipitada, não acha?
Claro, sem dúvida.
Muito boa sua iniciativa. O código parece bem legal também. No entanto, tenho preferido evitar todo este esforço. É uma guerra que nunca termina para seu projeto não ficar acoplado a framework nenhum. Enquanto não houver algo pronto que eu possa reaproveitar prefiro resolver as coisas de formas simples e facilmente refatoráveis. Acho que ambas idéias são aceitáveis.
Será mesmo? Acho que fazer o contrário é tão difícil quanto, ou seja, adaptar o domínio aos benefícios dos frameworks.
Se eu optar por não usar repositórios, vou fazer como? No meu contexto usar o QueryObject como se fosse um Bean junto com as classes de UI tem trazido ótimos benefícios e reduzido muito código.
Pois é, enfiei o hibernate dentro das classes de UI.
sergiotaborda:
Em vb usava smart-UI e sempre achei acoplado demais. Por isso que gosto de java e OO porque vc pode (deve?) não usar smart-UI.
smart-UI para mim é usar Jquery fazendo tabs e menus dinamicos e até ajax… mas as logicas de manipulação, qeury, etc é tudo no codigo back-end por causa da reusabilidade.
O que estou implementando não é tão radical quanto se propõe o Smart-UI. Só que o ideal é que o Domain possa ser facilmente acessado e manipulado por este “Smart-UI”. Por isso o repositorio pra mim não tem ajudado. Mantê-lo implica em escrever bem mais código. Simples assim.
F
feliperod
euprogramador:
Pessoal, que bom que o post tenha dado esta discursão tão produtiva para a comunidade.
realmente é bom ter várias cabeças pensando junto, estou implementando uma abordagem de Fluent interfaces para o meu Repositorio onde tenho métodos que fazem chamada da seguinte forma:
Se se trata de fluent interface, eu entendo que você está listando repositórios ao invés de usuários. Como eu li:
“listagem de usuarioRepositorio igual Carlos Alberto e igual ativo, ordeando por nome.”
Talvez se fosse usuario.igual("nome","Carlos Alberto").igual("ativo",true).ordenadoPor("nome",descending).listagem(1,40);
Aí sim, ficaria bem melhor.
Ainda daria pra otimizar, já que faz parte do usuário mesmo, pode diminuir o uso de parametros e passar a usar metodos com o nome real e de quebra, ainda eliminaria a dependencia que o repositorio tem da estrutura do seu aggregate. Imagine se vc remover o campo ativo. Causará side effect em várias chamadas desse repositorio.
Outra coisa que reparei é que nesse caso aí você está criando um query object builder, como o taborta mencinou no outro tópico. Esse código é muito bonito pra infra estrutura, mas no repositório eu colocaria algo mais objetivo. Para ter uma idéia melhor do que estou falando, procure ler sobre o Supple Design. Ele determina práticas como IntentionReavelingInterfaces de forma que sua interface revela o que deve ser feito.
Pode chamar esse query object builder direto de dentro do repositorio se quiser, mas leve em consideração o que eu escrevi acima. =)
E
euprogramador
O que acontece é o seguinte eu tenho os ManagedBeans do jsf que pertence a camada de aplicação, e coloquei a interface do repositório na camada de dominio e a implementação na infraestrutura, desta forma que demonstrei o repositório realmente sabe demais sobre a infraestrutura, o que recomenda então é criar um objeto que será responsável por acessar o banco e ficará na infraestrutura, e tanto o managed bean e o repositório o acessaria?
...// método da classe que implementa o repositoriopublicList<Usuario>recuperarUsuariosNaoAtivos(){returnusuario.igual("ativo",false).ordenadoPor("nome",descending).listagem();}
Seria assim?
Outra, o que tenho notado com DDD é que o código de negócio (Service) fica bem pequeno, mas temos muito código nas camadas para suportar o serviço, é assim mesmo?
E
euprogramador
Obrigado pela referência estou olhando…
F
feliperod
talvez assim fique melhor. Não sei… tem que avaliar o caso.
public void listar(){
listaDeClientes = usuario.withName("Carlos Alberto").ativo(true).repositorio().ordenadoPor("nome",descending).listagem(1, 40);
}
Acho que essa interface pro repositorio está boa sim. O nome do método é bem explicativo. Talvez fique melhor se você achar um jeito de dizer que é ordenado. Isso normalmente é resolvido por named paramaters em linguagens dinâmica. No Java pode ser inviável. Mas vale tentar.
euprogramador:
Outra, o que tenho notado com DDD é que o código de negócio (Service) fica bem pequeno, mas temos muito código nas camadas para suportar o serviço, é assim mesmo?
O Código de negócio deve ficar na camada de domain. Nos Services, Entities, Value Objects.
É um assunto mesio extenso pra explicar pelo forum sem ser abstrato demais. Seria ótimo se você pudesse ir no mini-curso gratuito que vai ter. Eu explico essa parte.
Mas de qq forma, as outras camadas não devem conter regras de negócio. Verifique se o Service que você mencionou é o Service que o DDD menciona (conceitualmente). Verifique se a sua camada de domain possue um limite claro… Verifique se cada camada está cumprindo unica e exclusivamente o seu papel.
Ah… cuidado pra não confundir regra de negócio com regra de apresentação.
E é isso. =)
E
euprogramador
Onde vai ser? eu sou de brasília.
F
feliperod
euprogramador:
feliperod:
Seria ótimo se você pudesse ir no mini-curso gratuito que vai ter. Eu explico essa parte.
Onde vai ser? eu sou de brasília.
Vai ser em sampa… =(
Mas quem sabe a gente marca um em Brasilia qualquer dia desses. Só arrumar lugar e rachar as despesas da viagem entre a galera aí que eu vou. =)
QQ coisa me contata em PVT.
E
euprogramador
feliperod:
Onde vai ser? eu sou de brasília.
Vai ser em sampa… =(
Mas quem sabe a gente marca um em Brasilia qualquer dia desses. Só arrumar lugar e rachar as despesas da viagem entre a galera aí que eu vou. =)
QQ coisa me contata em PVT.[/quote]
De boa, a gente pode ver sim, valeu;
S
sergiotaborda
Crio os testes automatizados numa boa. Conclusão precipitada, não acha?
Não acho. Aposto que vc tem grande dificuldade em testar o seu sistema sem ui e sem banco de dados e que provavelmente não usa um servidor de continuidade.
Isso não é dificil, é impossivel. toda a aplicação é amarrada a aquilo que se chama a plataforma de aplicação.
A plataforma de aplicação é um “framework” que vc usa para criar a aplicação. normalmente vc cria esta plataforma
fazendo uma “mushup” de frameworks que tratam partes especificas (Spring para Ioc , Hibernate para persistencia, JSF para apresentação, CFX para webservices, Commons-upload para tratar downlods , etc…) Só que é meio frankeinstein. Vc não isola esses frameworks e um dia vc bate com “putz não dá para fazer isso no X” onde X é um dos frameworks.
Essas plataformas frankeinstein funcionam bem durante um tempo, mas não para sempre.
Já existe algo pronto. os frameworks “on rails” são isso mesmo. E são mais ainda fazendo integração com ferramentas como compiladores, mavem e outros. o Grails é um exemplo prático. Ele usa Spring, hibernate , etc ,mas vc não precisa vê esses frameworks.
O MiddlHeaven não segue o caminho on rails, mas é uma plataforma de aplicação. A ideia é dependender apenas dela e deixar ela depender de quem for preciso.
Um exemplo, o jasperReports é excelente para integração com outros frameworks “acima”. Já o JFreeReport é uma porcaria.
T
Thiago_Senna
Crio os testes automatizados numa boa. Conclusão precipitada, não acha?
Não acho. Aposto que vc tem grande dificuldade em testar o seu sistema sem ui e sem banco de dados e que provavelmente não usa um servidor de continuidade.
Não utilizo servidor de continuidade. Testo sem a camada de UI numa boa. Testo Domain + Persistência pois não acho necessário separá-los. Para casos onde é muito importante testar o negócio sem persistência é só usar mock. Qual é a dificuldade nisso?
F
feliperod
Crio os testes automatizados numa boa. Conclusão precipitada, não acha?
Não acho. Aposto que vc tem grande dificuldade em testar o seu sistema sem ui e sem banco de dados e que provavelmente não usa um servidor de continuidade.
Não utilizo servidor de continuidade. Testo sem a camada de UI numa boa. Testo Domain + Persistência pois não acho necessário separá-los. Para casos onde é muito importante testar o negócio sem persistência é só usar mock. Qual é a dificuldade nisso?
Não vou opinar se está certo ou se está errado. Mas eu daria uma dica para você ler sobre benefícios do TDD. O TDD consiste em escrever o teste antes do código. Isso facilita o design de cada classe. Individualmente. Nesse caso, por nào separar o Domain da persistência, fica claro que não são testes unitários.
Outra coisa é que dificuldade para testar individualmente siginifica, na maioria dos casos, problemas de design.
Vale a pena investigar.
T
Thiago_Senna
feliperod:
Não vou opinar se está certo ou se está errado. Mas eu daria uma dica para você ler sobre benefícios do TDD. O TDD consiste em escrever o teste antes do código. Isso facilita o design de cada classe. Individualmente. Nesse caso, por nào separar o Domain da persistência, fica claro que não são testes unitários.
Outra coisa é que dificuldade para testar individualmente siginifica, na maioria dos casos, problemas de design.
Vale a pena investigar.
Sempre que escrevo testes é utilizando TDD. Se eu não escrever os testes primeiros eu tenho certeza q não vou escrever os testes depois.
Talvez o problema não esteja exatamente nos testes. Como puderam notar, sou um tanto “revoltado”, rsrs. Eu meio que cansei desta arquitetura defensiva onde se faz tudo pensando de que no futuro alguem vai mudar o mecanismo de persistência, de que derrepente o cliente muda o framework de UI entre outras coisas.
Sempre que pegamos um projeto e precisamos produzir vejo meu tempo sendo consumido criando interfaces, sua respectiva implemetação ao invés de simplesmente criar a implementação. Isso é revoltante pq analisando qualquer outra linguagem vemos que essa separação absurda só acontece na comunidade java. Resumindo… simplesmente quero resolver o problema e acabo me vendo a todo momento lidando com um monte de burocracia que todo programador acha que não pode viver sem.
Oras, se um desenvolvedor conhece bem os benefício de criar sua arquitetura com tudo separadinho, se ele por acaso querer juntar tudo de novo será que não pode sair alguma coisa boa daí?
Com certeza separar tudo não está errado. Mas juntar tudo denovo é o que estou testando fazer. É legal remar contra a maré
UPDATE: Obs: Alguns dos meus testes não se enquadram como teste unitário. Mas já é algum teste automatizado e aplico TDD.
S
sergiotaborda
Não pode. Esta é a vantagem de entender os principios de OO.
Vc pode pensar , dentro do seu espectro de experiencia, que assim é melhor. Pode ser mais rápido, mas não é melhor.
O desacoplamento não se faz porque o banco pode mudar, mas porque se usam 2 bancos (um “real” e um de testes).
O desacoplamento não é uma decoração, é uma necessidade. Mas se vc não desacopla , bom é com vc. Sempre pode refactorar depois
O ponto é o seguinte : aquilo que é bem feito por design não precisa se refactorado. Refactorar , ao contrário do que muita gente pensa, não é uma tecnica salva tudo mas sim a exumação de código morto, mal feito, ruim, acoplado, etc… Refactorar serve para tornar seu codigo melhor, mas se seu codigo já nasce bom, não ha porque refactorar = não se perde tempo com isso.
T
Thiago_Senna
:?
Sim, concordo em partes.
Talvez não estejamos nos entendendo aqui. Isso pq tenho conseguido ter uma base pra testes e desenv.
Acho que essa é a idéia - refatorar se necessário.
Então não precisa de testes também, certo? Em minha opinião, independente do design, é passível de refatoração.
Aqui realmente descordamos, mas cada um cada um No meu ver, um dos benefícios mais interessantes do TDD é me dar garantia de que posso refatorar.
S
sergiotaborda
Acho que essa é a idéia - refatorar se necessário.
Então não precisa de testes também, certo? Em minha opinião, independente do design, é passível de refatoração.
Aqui realmente descordamos, mas cada um cada um No meu ver, um dos benefícios mais interessantes do TDD é me dar garantia de que posso refatorar.
Existe refactorar e existe refactorar. Existe vc refactorar porque o seu codigo é uma porcaria e não atende a uma nova demanda e existe refactorar porque o seu codigo não é abstrato o suficiente. A primeira forma é um outro tipo de POG que básicamente assenta no principio “se posso refactorar porquê fazer isso agora?” A segunda acontece quando vc não tinha informação suficiente para ter abstraido mais, agora que tem essa informação a abstração é natural. Este é o tipo “saudável” de refactoração.
Agora, lá pq vc precisa abstrair não significa que consegue. Se o seu design é bom, vc não pensa sequer em refactorar e sim em implementar de um jeito diferente a interface X ou Y. Se o seu design é bom, vc não pensa em implementar um novo tipo de banco de dados (tipo = XML, LDAP , map/reduce) e sim configurar uma nova conexão. Entende o nivel da diferença ?
TDD não dá garantia de um bom design. Aliás nenhuma *DD dá essa garantia. Para isso precisa voltar ao B-A-BA de OO e entender as coisas como elas são. E quandio vc faz isso vc não precisa de *DD.
O que lhe dá garantia de (boa) refactoração é um bom design. O design com TDD tende a ser melhor que sem TDD porque vc precisa exercitar as coisas isolamente e isso obriga a um desacoplamento maior e a uma inversão de controle mais agressiva. Contudo, essas mesmas propriedades podem ser adquiridas sem TDD. Ou seja, TDD é melhor que nada, mas OO é melhor que TDD.