Estou com um problema, já pesquisei aqui no fórum, mais ainda não consegui entender o mecanismo.
O meu objetivo por hora é ter um DaoSql, um DaoOracle e um DaoObjectMemory, onde tenho métodos que acessam Sql server, oracle e objetos na memória (para testes) respectivamente.
Então tenho uma esquema assim:
//Recuperar os dependentes de um titular
public class Titular
{
public List<Dependentes> GetDependentes()
{
return Dependente.GetDependentesDo(this);
}
}
public class Dependente
{
public List<Dependente> GetDependentesDo(Titular titular)
{
return RepositoryDependentes.GetDependentesDo(titular);
}
}
public classe RepositoryDependentes()
{
public List<Dependente> GetDependentesDo(Titular titular)
{
string Query = "Select .....";
data = DaoSql.ExecutaQuery(Query);
foreach (data)
{
//monto dependentes
}
return DependentesDoTitular;
}
}
A intenção é possibilitar RepositoryDependentes.GetDependentesDo(titular) trazer dependentes do SQL ou do Oracle ou da memória. Provavelmente terei que usar um factory, mais onde? e como?
No caso de ter apenas databases (sql e oracle) eu até consigo me virar bem pois as coisas são bem parecidas, mais quando entra a possibilidade de trabalhar apenas com objetos em memória eu me enrolo, pois o tratamento é bem diferente, não tem concexao, etc.
Estou com um problema, já pesquisei aqui no fórum, mais ainda não consegui entender o mecanismo.
O meu objetivo por hora é ter um DaoSql, um DaoOracle e um DaoObjectMemory, onde tenho métodos que acessam Sql server, oracle e objetos na memória (para testes) respectivamente.
Então tenho uma esquema assim:
//Recuperar os dependentes de um titular
public class Titular
{
public List<Dependentes> GetDependentes()
{
return Dependente.GetDependentesDo(this);
}
}
public class Dependente
{
public List<Dependente> GetDependentesDo(Titular titular)
{
return RepositoryDependentes.GetDependentesDo(titular);
}
}
public classe RepositoryDependentes()
{
public List<Dependente> GetDependentesDo(Titular titular)
{
string Query = "Select .....";
data = DaoSql.ExecutaQuery(Query);
foreach (data)
{
//monto dependentes
}
return DependentesDoTitular;
}
}
A intenção é possibilitar RepositoryDependentes.GetDependentesDo(titular) trazer dependentes do SQL ou do Oracle ou da memória. Provavelmente terei que usar um factory, mais onde? e como?
No caso de ter apenas databases (sql e oracle) eu até consigo me virar bem pois as coisas são bem parecidas, mais quando entra a possibilidade de trabalhar apenas com objetos em memória eu me enrolo, pois o tratamento é bem diferente, não tem concexao, etc.
Obrigado a todos.[/quote]
Procure/Pesquise/Estude o padrão Strategy. Resolve seu problema.
Vlw ae pela ajuda, eu já conhecia o strategy, mais não consigo ver como aplicar isso neste cenário. Meus repositórios são bem diferentes uns dos outros. RepositoryTitular possui métodos muito diferentes de RepositoryDependente. Eu teria que criar uma estratégia para cada repositório?
Teria então RepositorioTitularEstrategiaSQL, RepositorioTitularEstrategiaOracle etc?
Talvez eu não tenha entendido bem seu problema. Vamos lá:
Você precisa inverter o controle do repositório, porém suas implementações são diferentes, é isso?
Você pode ter uma interface em comum entre eles, não pode?
Ahan… todas implementando Repository (que teria os comportamentos do negócio) aí então você poderia criar seus dependentes passando uma instância da sua necessidade de momento. Tbm poderia inverter o controle em tempo de execução talvez criando um setRepositoryXXX nela.
Seu problema pode facilmente ser resolvido com DI (Dependency Injection).
Se vc não optar por um container de DI, vc pode fazer uma fabrica abstrata de DAOs pra fazer esta criação…
No link, vá em Using Abstract Factory Pattern
Vc seguio os padrões corretamente. O seu problema é com a querie. Vc está escrevendo em SQL e portanto quando usa o DAOInMemory vc teria que intrepretar o SQL e isso é !@#$@#$.
Esse problema acontece porque vc não isolou completamente o contrato do DAO da tecnologias subjacente: i.e. vc continua passando frases SQL como Strings.
Entenda que a String com SQL lá dentro é o Query Object ( Objeto de Pesquisa) do seu DAO. É esse objeto que ele intrepreta para fazer a pesquisa ( se ele delega isso vc não sabe).
A solução é portanto construir um Query Object que não tenha SQL lá dentro nem seja um String. E escrever algo como isto
public classe RepositoryDependentes()
{
public List<Dependente> GetDependentesDo(Titular titular)
{
// Select * from Dependente where titular = ?
Criteria criteria = Criteria.search("Dependente").add(Restriction.eq("titular", titular.getID()));
data = DaoSql.ExecutaQuery(criteria );
foreach (data)
{
//monto dependentes
}
return DependentesDoTitular;
}
}
Na memória vc pode ter um Map<String, List> onde o string é o nome da classe
Para SQL vc simplesmente constroi um SQL baseado nos dados setados no critério e executa via JDBC.
TitularRepository tem GetTitularAtivo no DependenteRepository tem GetDependentesDo(Titular titular). Meus repositórios são bem específicos, não sei se isso é correto ou é um problema de design. Se for como eu faria já que tenho necessidades diferentes para cada entidade?
Sérgio, como sempre você clarea minhas idéias, vlw.
É exatamente essa a minha dificuldade, deixar as querys menos específicas, mais seguindo sua sugestão eu tenho um repositório que monta critérios e um Dao que interpreta critérios, correto?
A criação desses critérios e suas variações, corrija-me se estiver errado, é bem complexa e trabalhosa, pois tenho uma grande quantidade de posssibilidades (igual, diferente, maior, menor, exists, union select dentro de select etc etc). Neste caso não seria mais prático partir para um Hibernate da vida? Isso resolveria meus problemas ou uma coisa nada tem a ver com a outra?
TitularRepository tem GetTitularAtivo no DependenteRepository tem GetDependentesDo(Titular titular). Meus repositórios são bem específicos, não sei se isso é correto ou é um problema de design. Se for como eu faria já que tenho necessidades diferentes para cada entidade?
Sérgio, como sempre você clarea minhas idéias, vlw.
É exatamente essa a minha dificuldade, deixar as querys menos específicas, mais seguindo sua sugestão eu tenho um repositório que monta critérios e um Dao que interpreta critérios, correto?
A criação desses critérios e suas variações, corrija-me se estiver errado, é bem complexa e trabalhosa, pois tenho uma grande quantidade de posssibilidades (igual, diferente, maior, menor, exists, union select dentro de select etc etc). Neste caso não seria mais prático partir para um Hibernate da vida? Isso resolveria meus problemas ou uma coisa nada tem a ver com a outra?
Trabalhosa sim, mas complexa não. É básiamente dar à manivela. Não ha nenhum segredo. Para criar SQL é conatenar Strings ( com StringBuilder, claro). Tlv o de memeoria seja mais dificil , mas com Refletion é facil. Tlv ve tenah que criar muito codigo, mas ele será bem simples em essencia.
Se ele atende as necessidades do seu projeto use-o. Mas tenha a certeza disso antes de o começar a usar.
É dificil criar codigo TDD-friendly com o uso de Hibernate direto. Com o Seu dao é facil é só criar um TestDAO ou utilizar o InMemoryDAO ( ou fazer um esquela de herança, sei lá… )
Se o seus sistema é Swing com JBoss ou algo assim, tb não usaria Hibernate. Vc pode ter um DAO local no Swing, com cache e comunicar com um DAO ligado a banco de dados no servidor. A sua aplicação não saberá a dferença já que só vê o DAO.