Em termos de arquitetura, uma camada de abstração de banco de dados, como o Entity Framework da Microsoft, anula a necessidade de uma Camada de Acesso a Dados separada?

11

Do jeito que era

Durante anos, organizei minhas soluções de software da seguinte forma:

  • Data Access Layer (DAL) para abstrair o negócio de acessar dados
  • Business Logic Layer (BLL) para aplicar regras de negócios a conjuntos de dados, manipular autenticação etc.
  • Utilitários (Util), que é apenas uma biblioteca de métodos utilitários comuns que construí ao longo do tempo.
  • Camada de apresentação, que pode ser, obviamente, web, desktop, móvel, qualquer que seja.

Do jeito que está agora

Nos últimos quatro anos, eu tenho usado o Entity Framework da Microsoft (sou predominantemente um desenvolvedor .NET) e estou descobrindo que ter o DAL está se tornando mais complicado do que limpo, devido ao fato de que o Entity Framework já fez o trabalho que meu DAL costumava fazer: abstrai o negócio de executar CRUDs em um banco de dados.

Portanto, normalmente acabo com um DAL que possui uma coleção de métodos como este:

public static IQueryable<SomeObject> GetObjects(){
    var db = new myDatabaseContext();
    return db.SomeObjectTable;
}

Em seguida, no BLL, esse método é usado como tal:

public static List<SomeObject> GetMyObjects(int myId){
    return DAL.GetObjects.Where(ob => op.accountId == myId).ToList();
}

Este é um exemplo simples, é claro, pois o BLL normalmente teria várias outras linhas de lógica aplicadas, mas parece um pouco excessivo manter um DAL para um escopo tão limitado.

Não seria melhor simplesmente abandonar o DAL e simplesmente escrever meus métodos BLL como tal:

public static List<SomeObject> GetMyObjects(int myId){
    var db = new myDatabaseContext();
    return db.SomeObjectTable.Where(ob => op.accountId == myId).ToList();
}

Estou pensando em retirar o DAL de projetos futuros pelas razões expostas acima, mas, antes de fazê-lo, queria pesquisar a comunidade aqui por suas retrospectivas / previsões / opiniões antes de seguir adiante em um projeto e descobrir um problema que não resolvi ' t antecipar.

Quaisquer pensamentos são apreciados.

Atualizar

O consenso parece ser que um DAL separado não é necessário, mas (fazendo minha própria inferência aqui) é uma boa idéia para evitar o bloqueio do fornecedor. Por exemplo, se eu tiver um DAL que abstraia as chamadas EF, como ilustrado acima, se eu sempre mude para outro fornecedor, não preciso reescrever minha BLL. Somente essas consultas básicas no DAL precisariam ser reescritas. Dito isto, acho difícil imaginar um cenário em que isso aconteceria. Eu já posso fazer um modelo EF de um banco de dados Oracle, o MSSQL é um dado, tenho certeza de que o MySQL também é possível (??), portanto, não tenho certeza se o código extra concederia um ROI valioso.

Matt Cashatt
fonte
3
Qual é a diferença entre a camada de acesso a seus dados e a EF? A EF não é uma camada de acesso a dados? Únicas razões que eu posso ver para manter a sua própria abstração entre a lógica de negócios e EF é fazer arrancar mais fácil para testar e bloqueio fornecedor evitar no.
Marjan Venema
2
Esse é o meu ponto - não há diferença na minha opinião, mas estou procurando por contrapontos. Obrigado.
Matt Cashatt
3
Pessoalmente, não vejo razão para criar um DAL separado, porque EF / NHibernate são camadas de acesso a dados em si. Como Marjan mencionou, com a EF, você pode considerar se pode ver o fornecedor do banco de dados mudando; no NHibernate, você pode trocar os drivers em uma linha de código (mesmo o driver SQLite para testes na memória), portanto seria um código desnecessário (IMO).
Patryk Ziek
3
Não há necessidade de dois DALs. Como outros já declararam, mantenha sua BLL, mas tome cuidado para não prendê-la em construções específicas do fornecedor. Eu sempre gosto de ver as coisas chegarem ao nível da string ou do número inteiro. Então eu sei que poderia facilmente expor toda a junção BLL / DAL através de um canal muito primitivo, como serviços da Web, porta serial, link de telégrafo, apenas brincando.
21313 Andyz Smith
1
Atualização: esta camada extra pode facilitar muito a Unittests do busineslayer, porque zombar / arrancar / fingir GetMyObjects(int myId)é mais fácil do que zombar / arrancar / fingir GetObjects.Where(ob => op.accountId == myId).ToList().
K3b

Respostas:

6

Não tenho certeza se esta é a resposta que você está procurando ... mas aqui vai.

Fazemos isso para manter as coisas separadas / organizadas. Sim, EF / NHibernate são acesso a dados .. mas limitamos seu uso ao seu próprio assembly com uma configuração genérica de repositório. Esse assembly também contém todos os nossos mapeamentos do NHibernate, Session Factory, código para manipular vários bancos de dados, etc.

Ainda o chamamos de "Camada de acesso a dados", porque o conjunto inteiro existe para oferecer suporte ao nosso ORM.

Provavelmente, devo observar que nosso aplicativo principal faz referência a 5 bancos de dados, possui aproximadamente 4-500 objetos / mapeamentos de domínio e vários esquemas. Portanto, essa configuração faz sentido para nós. Talvez para um aplicativo menor você pule esse assembly, mas .. Eu sou um otário por código organizado e provavelmente faria isso de qualquer maneira :)

Simon Whitehead
fonte
2

Eu vejo o EF e o DAL como componentes separados em um sistema Enterprise. A camada de acesso a dados é uma abstração usada por outros serviços para executar a persistência e o gerenciamento de dados. Normalmente, os Entity Frameworks criam uma API agradável em torno da consulta, atualização, exclusão e inserção, no entanto, no núcleo, eles ainda exigem uma conexão direta com a fonte de dados de back-end. Portanto, qualquer tipo de roteamento ou firewall interrompe o funcionamento do EF, exigindo que você crie um componente de mediação EF.

Aqui está um exemplo de alto nível que mostra onde DAL e EF se encaixam:

-------------    -------                                    ----------------    ------
| Service A | -> | DAL | -> { LOCAL / LAN / WAN ACCESS } -> | DAL BACK-END | -> | EF |
-------------    -------                                    ----------------    ------

Foi minha experiência que um design melhor é nunca permitir que a lógica de negócios ou as implementações de serviço tenham acesso direto à camada EF. Em vez disso, forneça uma abstração para trabalhar com todos os dados persistentes, o que permite enviar solicitações por cabo ou executá-las localmente.

Esse design apresenta algumas abstrações com vazamentos. Portanto, deve ser considerado caso a caso.

Algumas perguntas a serem feitas:

  • Todos os componentes que acessam seus dados poderão obter uma conexão com o armazenamento de dados de back-end?
  • Seu EF permite agregar conjuntos de dados em diferentes tipos de repositórios de dados? Por exemplo, usando um banco de dados SQL com MongoDB para documentos.
Andrew T Finnell
fonte
1

Atualmente, a questão de alterar ou não o armazenamento de dados é mais interessante do que costumava ser, já que a questão pode não ser apenas se você trocaria ou não o MS SQL ou o Oracle SQL, mas a questão maior sobre se você pode usar em várias ofertas de armazenamento de dados NoSQL como seu repositório de dados.

Se houvesse uma possibilidade séria desse tipo de alteração, pode ser valioso manter seu código EF isolado dentro do seu DAL, para que você possa introduzir um novo DAL no futuro que mapeie suas solicitações de repositório para um banco de dados NoSQL. Pode ser que essa mudança acabe com uma reescrita por atacado da sua BLL de qualquer maneira, devido a suposições relacionadas ao banco de dados que se arrastam, é claro.

Da mesma forma, a EF dentro de um DAL provavelmente tornaria a simulação do acesso a dados para seus testes de unidade de código BLL mais simples.

Portanto, minha opinião é que a EF (ou outro ORMS) não anula necessariamente a necessidade de uma camada de acesso a dados.

Alex White
fonte