O que é código lógico de negócios e o que é código de acesso a dados? Qual é a diferença?

5

Pergunto isso porque parece que as pessoas geralmente consideram o código que entra em uma implementação do DAO ou do Repositório como "código de acesso a dados", enquanto o código usa diretamente esses DAOs / Repositories como "código de lógica de negócios".

No entanto, isso não parece fazer sentido lógico.

Considere um método de serviço de negócios com código como o seguinte (usando Java, mas seria semelhante em C #, etc.):

public BigDecimal computeCustomerTotal(Customer customer) {
    List<Order> orders = orderRepository.findByCustomer(customer);

    BigDecimal total = orders.stream()
        .filter(Order::isActive).map(Order::getTotal).reduce(ZERO, BigDecimal::add);

    return total;
}

Claro, a implementação acima não faz uso "adequado" das capacidades de um banco de dados, mas tenha paciência comigo. O ponto aqui é que, eu suponho, todos concordam que contém apenas código de lógica de negócios, com Customer e Order sendo entidades domínio (ou seja, eles não são objetos "dados").

Então, e se eu quiser fazer certo, movendo toda a computação para o banco de dados, em vez de executar no programa cliente? Se eu seguir "sabedoria convencional", criaria um novo método no repositório:

public BigDecimal getCustomerTotal(Customer customer) {
    BigDecimal total = performQuery(
        "select sum(o.total) from Order o where o.customer = ?1 and o.active",
        customer);

    return total;
}

(Assume que performQuery é um método utilitário baseado em JPA que usa um JPA-QL frase com argumentos opcionais).

A segunda implementação é obviamente melhor que a primeira, já que provavelmente tem um desempenho melhor e faz uso adequado das tecnologias subjacentes (JPA / Hibernate e um banco de dados relacional).

O problema, porém, é que a lógica de negócios (a regra de que apenas pedidos ativos devem ser considerados) foi movida de um método de serviço de negócios para um (suposto) método de acesso a dados, por meio de uma simples implementação > mudança. Além disso, este código que agora está no DAO / Repositório não realmente realmente sabe sobre preocupações com acesso a dados, como o mapeamento de tipos de entidade e atributos para tabelas e colunas, ou sobre o código SQL real que é obtido gerado e enviado para o mecanismo de banco de dados.

Não seria mais lógico considerar os métodos ambos como contendo apenas o código lógica de negócios , e simplesmente livrar-se do DAO / Repository / DAL?

Pessoalmente, não vejo nenhum código de acesso a dados, e para mim coisas como DAOs, Repositórios ou "camadas de acesso a dados" (DAL) são na realidade anti-padrões. Observe que, mesmo ao usar o JDBC + SQL em uma implementação do DAO / Repository, ele conterá inevitavelmente a lógica de negócios, normalmente na forma de cláusulas "where".

    
por Rogério 03.07.2015 / 23:54
fonte

3 respostas

4

A camada de banco de dados destina-se a isolar o restante do aplicativo dos detalhes do banco de dados - como fazer uma conexão, a sintaxe usada para falar com o mecanismo de banco de dados, etc.

A versão do .Net Entity Framework do seu código seria:

var id = customer.id;
var customerOrdersTotal = db.Orders.
                          Where(o => o.CustomerId == id && o.Active).
                          Sum(o => o.Total);

Note que isso seria traduzido para o sql que sua versão do JPA usaria, mas a mesma coisa poderia ser feita sem envolver o sql.

Se você tem um cliente que tem pedidos, então seria:

var customerOrdersTotal = customer.Orders.
                          Where(o => o.Active).Sum(o => o.Total);

E esta versão pode ser escrita independentemente de a Orders ser uma lista virtual ou uma lista real de pedidos.

A empresa não se importa onde os dados são mantidos ou como são recuperados. O objetivo de um DAL é abstrair o "como esse bit de dados é recuperado" e transformá-lo em apenas o necessário (ou seja, inevitável) "como solicitar os dados que eu quero". Sem um DAL você tem que misturar as duas funções juntas, o que significa que você não pode mudar uma sem mudar a outra.

Note que, na metade do tempo, você nunca acaba fazendo nenhuma mudança ... mas quando você faz isso é uma dor real se eles estão misturados.

Editar: acrescentarei que sua implicação de que cláusulas "where" no código de acesso a dados é uma preocupação comercial está incorreta. A camada de dados existe para atender às necessidades de negócios. Os dados podem ser divididos e servidos em um número infinito de maneiras, algumas mais úteis que outras. Mover uma condição da camada de negócios para a camada de dados significa simplesmente que a solicitação é comum o suficiente para ser incluída nas maneiras que são fornecidas prontamente. Impedir novos pedidos quando pedidos ativos existentes excedem $ X é uma decisão comercial.

    
por 04.07.2015 / 00:35
fonte
1

What is business logic code and what is data access code, and what's the difference?

Há uma resposta curta para isso:

a) Código, que é usado para abrir uma conexão com um banco de dados, para recuperar dados, fazer mapeamento OR etc. é chamado data access code

 static public int AddProductCategory(string newName, string connString)
 {
     Int32 newProdID = 0;
     string sql =
         "INSERT INTO Production.ProductCategory (Name) VALUES (@Name); "
         + "SELECT CAST(scope_identity() AS int)";
     using (SqlConnection conn = new SqlConnection(connString))
     {
         SqlCommand cmd = new SqlCommand(sql, conn);
         cmd.Parameters.Add("@Name", SqlDbType.VarChar);
         cmd.Parameters["@name"].Value = newName;
         try
         {
             conn.Open();
             newProdID = (Int32)cmd.ExecuteScalar();
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex.Message);
         }
     }
     return (int)newProdID;
 }

Exemplo retirado de MSDN

b) Código, que é usado para transformar esses dados ou conatando as regras, quando recuperar esses dados é chamado business logic

Ambos são responsabilidades diferentes e geralmente são implementados em diferentes camadas do seu aplicativo:

a) Em uma camada às vezes chamada de service-layer fica a lógica, quando recuperar que tipo de dados e como esses dados são tratados, também conhecido como business logic

b) Caso você esteja implementando o Padrão de repositório : este é o lugar onde o data acces code vive.

The point here is that, I assume, everyone agrees it contains only business logic code, with Customer and Order being domain entities (ie, they are not "data" objects).

Não. É data access code , recupera dados de maneira relevante para a lógica de negócios.

Wouldn't it be more logical to regard both methods as containing only business logic code, and just get rid of the DAO/Repository/DAL altogether?

Nenhum dos métodos contém business logic . É realmente apenas access code . A razão pela qual você filtra os dados como você faz é levar por preocupações comerciais, mas isso não os torna business logic .

Personally, I don't see any data access code there, and to me things like DAOs, Repositories, or "data access layers" (DAL) are in reality anti-patterns. Note that even when using JDBC + SQL in a DAO/Repository implementation, it will inevitably contain business logic, typically in the form of "where" clauses.

Talvez você devesse pensar sobre sua definição de business logic . Esses padrões não são de forma alguma anti-patterns , esses padrões permitem uma separação clara das preocupações.

    
por 04.07.2015 / 09:34
fonte
0

Parece-me que você está perdendo uma definição de classe.
Declare uma classe CustomerOrders com GetOrdersTotal method.
É um objeto de negócios puro. Não há tal tabela no banco de dados. Ele envolve um Order DAO e aplica regras de negócios nele (ordem ativa, filtro por ID do cliente). Então, OrderRepository é seu DAL e CustomerOrders é seu BL

    
por 04.07.2015 / 19:48
fonte