No caso, o repositório serviria como fachada para a camada de persistência. Ou seja, só o fato de minha camada de negócios depender de uma abstração da persistência já vale o uso.
[/quote]
Podemos entender o repositorio como uma instancia do padrão Façade , mas não com a camada de persistencia.
O repositorio é principalmente um Façade para a camada de busca. Esta camada normalmente tem a ver com a persistencia, mas não é necessáriamente assim ( Lucene).
É necessário esclarecer é que Repository não tem métodos insert/update/delete como o DAO.
Ele só terá esses métodos em casos particulares em que a coleção de objetos é editada pelo proprio dominio.
Se os dados do dominio são alimentados fora dele, o repositorio não tem métodos de alteração.
Acontece que normalmente o dominio faz algum tipo de alteração e é então que é mais logico usar o repositorio como centralizador dessa necessidade. Mas isso é dar ao repositorio responsabilidades a mais. A base dele não é essa. Não é para isso que ele é criado. Não é para isso que ele existe. Mas uma vez que existe, ele pode também ter essas responsabilidade. ( por isso que nem todas as entidades têm um repositorio)
O DAO não é um objeto sozinho quando fazemos pesquisas. Eles usa alguma linguagem para essa pesquisa.
Estamos partindo do principio que o DAO tem essa linguagem. Se não tem, ele tem métodos especiais do tipo getClientesAtivos() o que o torna não reaproveitável e uma violação do principio de SoC. (um DTO-sabe-tudo)
Portanto, durante a pesquisa o DAO tem um objeto associado. Esse objeto (SQL=String, Criteria, queryObject, etc…) é que é o problema. Não queremos depender desse objeto. Se o DAO é reaproveitável queremos aproveitá-lo em outros sistemas. E ao mesmo tempo queremos ser livres de mudar nosso DAO por um melhor (por exemplo, um que usa melhores implementações ou avançados do JDBC ).
Mas se o DAO depende de uma linguagem de pesquisa e não isolamos essa linguagem, não podemos mudar de DAO.
Na prática, vc tem um DAO para banco de dados e usa SQL para os queries.Um dia vc quer lançar um demo readonly do seu sistema. Ai vc pensa em usar XML porque o overhead do banco seria inutil. Mas ai como vc vai transformar as queries SQL em XPath ? Colocar SQL como linguagem de procura de XML é estranho. Ai vc vai disistir do XML e forçar o uso de um banco em memoria (quando vc sabe que não quer isso). Vc se amarrou a si próprio (lock down) ao uso de SQL. O repositorio evita isso.
E relembro que não se troca de repositorio. Ele é sempre o mesmo. O repositorio é que troca de estratégia.
O repositorio não é definido por uma interface. Ele não é um contrato, é um “braço” do sistema.
Não. Imagine que eu crio um DomainStore muito bom , que usa QueryObject. Estas classes não dependem de dominio e não dependem de API de persistencia. Vc pensa: “legal, agora posso ligar o dominio com este storage porque não dependo do DAO. Os query objets não vão mudar porque o DomaisStore vai isolar isso de mim e traduzir o query para a tecnologia subjacente ( Xpath, SQL, etc…)”
Neste cenário o uso de Repository parece inutil. Só que uma outra empresa desenvolveu um DomainStore que é 100 vezes mais rápido que este. As queries são escritas de forma mais simples e é compativel com mais tecnologias de persistencia (bancos OO , por exemplo). Vc quer mudar para este novo DomainStore muito bom.
Mas vc não pode, porque teria que reescrever os queries com a nova API.
Se estiver usando repository, vc cria uma nova estratégia e pronto. Quando a empesa nova começar a cobrar pelo uso e vc não quiser pagar, vc volta à estratégia antiga.
Este exemplo é muito simples de entender. Todo o mundo usava JDBC com SQL. Todas as queries eram escritas directamente no codigo ( mesmo que dentro do DAO-sabe-tudo). Um dia veio o hibernate. Vc acha que alguem vai algum dia mudar aqueles SQL para Criterias do Hibernate ? Claro que não, porque isso custa dinheiro.
Claro que é sempre possivel refactorar um codigo e introduzir um repositorio onde nenhum existia antes. Afinal a pessoa/equipe aprendeu com seus erros. Mas isso tb é caro. A opção mais barata é usar o repositorio de um principio.
Agora, o repositorio pode receber objetos QueryObject e traduzir para o DAO. Mas ele também pode ter métodos do tipo getCLientsAtivos() e implementar directamente para o DAO. Do ponto de vista OO é a mesma coisa porque invocar find(QueryObject) ou getClientsAtivos() é a mesma coisa. Vc está enviando uma mensagem ao repositorio e ele responde. A escolha é sua.
Repare que se o repositorio usar queryObject esse query será especifico do dominio , logo, não ha perigo disso ter que mudar depois.