Estou curioso para saber quais são as desvantagens de usar o padrão ActiveRecord para acessar dados / objetos de negócios. A única coisa em que consigo pensar é que viola o Princípio da Responsabilidade Única, mas o padrão de RA é comum o suficiente para que esse motivo por si só não pareça "bom o suficiente" para justificar não usá-lo (é claro, meu A visualização pode ser distorcida, pois muitas vezes nenhum código com o qual trabalho segue nenhum dos princípios do SOLID).
Pessoalmente, eu não sou fã do ActiveRecord (com exceção de escrever um aplicativo Ruby on Rails, onde o AR parece "natural") porque parece que a classe está fazendo muito e o acesso a dados não deve depender da própria classe lidar. Prefiro usar Repositórios que retornam objetos de negócios. A maior parte do código com o qual trabalho tende a usar uma variação do ActiveRecord, na forma de (não sei por que o método é booleano):
public class Foo
{
// properties...
public Foo(int fooID)
{
this.fooID = fooID;
}
public bool Load()
{
// DB stuff here...
// map DataReader to properties...
bool returnCode = false;
if (dr.HasRows)
returnCode = true;
return returnCode;
}
}
ou, às vezes, a maneira mais "tradicional" de ter um public static Foo FindFooByID(int fooID)
método para os buscadores e algo semelhante ao de public void Save()
salvar / atualizar.
Entendo que o ActiveRecord normalmente é muito mais simples de implementar e usar, mas parece um pouco simples demais para aplicativos complexos e você pode ter uma arquitetura mais robusta encapsulando sua lógica de acesso a dados em um Repositório (sem mencionar que é mais fácil trocar estratégias de acesso a dados, por exemplo, talvez você use Procs armazenados + DataSets e queira mudar para LINQ ou algo assim)
Então, quais são as outras desvantagens desse padrão que devem ser consideradas ao decidir se o ActiveRecord é o melhor candidato para o trabalho?
fonte
A maior desvantagem do registro ativo é que o seu domínio geralmente fica fortemente associado a um mecanismo de persistência específico. Caso esse mecanismo exija uma mudança global, talvez da persistência baseada em arquivo para baseada em banco de dados ou entre estruturas de acesso a dados, TODAS as classes que implementam esse padrão podem mudar. Dependendo do idioma, estrutura e design, mesmo algo tão simples quanto alterar onde o banco de dados está localizado ou quem é o "proprietário", pode ser necessário percorrer todos os objetos para atualizar os métodos de acesso a dados (isso é incomum na maioria dos idiomas que fornecem acesso fácil para configurar arquivos com cadeias de conexão).
Também geralmente requer que você se repita. A maioria dos mecanismos de persistência possui muito código comum para conectar-se a um banco de dados e iniciar uma transação. O DRY (não se repita) lhe diria como codificador para centralizar essa lógica.
Também torna as operações atômicas complicadas. Se um grupo de objetos precisar ser salvo de maneira tudo ou nada (como uma fatura e suas linhas de fatura e / ou entradas de cliente e / ou GL), um objeto deve conhecer todos esses outros objetos e controlar sua persistência ( que amplia o escopo do objeto de controle; grandes registros interconectados podem facilmente se tornar "objetos divinos" que sabem tudo sobre suas dependências) ou o controle sobre toda a transação deve ser tratado de fora do domínio (e, nesse caso, por que você está usando AR?)
Também está "errado" de uma perspectiva orientada a objetos. No mundo real, uma fatura não sabe como se arquivar. Por que um objeto de código de fatura saberia como se salvar no banco de dados? Obviamente, a adesão excessivamente religiosa a "objetos deve apenas modelar o que seus colegas do mundo real podem fazer" levaria a modelos de domínio anêmicos (uma fatura também não sabe como calcular seu próprio total, mas divide o cálculo desse total para outro objeto é geralmente considerado uma má idéia).
fonte
A desvantagem básica é que isso torna seu modelo de domínio complexo, pois não apenas contém a lógica de negócios, mas também informações de persistência.
Portanto, a solução é fazer uso da implementação do ORM do Data Mapper . Isso separa a camada de persistência e agora estamos mais centrados na lógica de negócios da entidade. A doutrina é o ORM do Mapeador de Dados .
Mas essa abordagem também tem alguma complexidade. Para a consulta agora, você depende muito do Data Mapper, cria um ambiente orientado à consulta. Para simplificá-lo, outra camada é introduzida entre o Modelo de Domínio e o Mapeador de Dados, chamado Repositório .
Resumo do repositório da camada de persistência. Faz sentido da programação orientada a objetos no sentido, é uma coleção de todos os objetos do mesmo tipo (como todas as entidades armazenadas na tabela do banco de dados) e você pode executar operações nelas como operação de coleção, adicionar , remover . contém etc.
Por exemplo, para Entidade do usuário , haverá UserRepository que representa a coleção do mesmo tipo de objetos de usuário (armazenados na tabela de usuários) sobre os quais você pode executar a operação. Para consultar a tabela de usuários, ele usa o User Data Mapper, mas abstraiu para o modelo de domínio User .
O padrão do repositório é o tipo de Camada de Acesso a Dados , outro é o único objeto de acesso a dados. Diferenças O repositório possui o recurso Raiz Agregada
fonte