Che cos'è il codice di logica aziendale e qual è il codice di accesso ai dati e qual è la differenza?

5

Chiedo questo perché sembra che la gente di solito consideri il codice che va in un'implementazione DAO o Repository come "codice di accesso ai dati", mentre il codice che utilizza direttamente questi DAO / repository come "codice logico aziendale".

Tuttavia, questo non sembra logico.

Considera un metodo di servizio aziendale con codice simile al seguente (utilizzando Java, ma sarebbe simile in C #, ecc.):

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;
}

Certo, l'implementazione di cui sopra non rende "appropriato" l'uso delle funzionalità di un database, ma mi tiene con me. Il punto qui è che, presumo, tutti sono d'accordo che contiene solo codice di logica aziendale, con Customer e Order che sono entità dominio (cioè non sono oggetti "dati").

Quindi, cosa succede se voglio farlo nel modo giusto, spostando l'intero calcolo nel database, invece di eseguirlo nel programma client? Se seguo la "saggezza convenzionale", creerei un nuovo metodo nel repository:

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;
}

(Supponiamo che performQuery sia un metodo di utilità basato su JPA che accetta un JPA-QL frase con argomenti opzionali.)

La seconda implementazione è ovviamente migliore della prima, poiché probabilmente ha prestazioni migliori e fa un uso corretto delle tecnologie sottostanti (JPA / Hibernate e un database relazionale).

Il problema, tuttavia, è che la logica aziendale (la regola secondo cui solo gli ordini attivi dovrebbero essere considerati) è stata spostata da un metodo di servizio aziendale a un (presunto) metodo di accesso ai dati, attraverso una semplice implementazione cambia. Inoltre, questo codice che è ora nel DAO / Repository fa in modo che non sappia dei problemi di accesso ai dati, come il mapping da tipi di entità e attributi a tabelle e colonne o il codice SQL effettivo che ottiene generato e inviato al motore DB.

Non sarebbe più logico considerare i metodi entrambi come contenenti solo codice business logic , e semplicemente eliminare completamente DAO / Repository / DAL?

Personalmente, non vedo alcun codice di accesso ai dati lì, e per me cose come DAO, Archivi o "livelli di accesso ai dati" (DAL) sono in realtà anti-schemi. Si noti che anche quando si utilizza JDBC + SQL in un'implementazione DAO / Repository, sarà inevitabilmente contenuta la logica aziendale, in genere sotto forma di clausole "where".

    
posta Rogério 03.07.2015 - 23:54
fonte

3 risposte

4

Il livello database ha lo scopo di isolare il resto dell'applicazione dai dettagli del database - come creare una connessione, la sintassi utilizzata per comunicare con il motore db, ecc.

La versione di .Net Entity Framework del tuo codice sarebbe:

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

Si noti che questo verrà tradotto nella sql utilizzata dalla propria versione JPA, ma la stessa cosa può essere eseguita senza coinvolgere affatto sql.

Se hai un cliente che ha ordini, allora sarebbe:

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

E questa versione potrebbe essere scritta indipendentemente dal fatto che Ordini sia una lista virtuale o un vero elenco di ordini.

All'azienda non importa dove vengono conservati i dati o come vengono recuperati. Il punto di un DAL è di astrarre il "come viene recuperato questo bit di dati" e trasformarlo nel necessario (cioè inevitabile) "come richiedere i dati che voglio". Senza un DAL devi mischiare le due funzioni insieme, il che significa che non puoi cambiarne una senza cambiare l'altra.

Da notare che circa la metà delle volte non finisci mai per apportare modifiche ... ma quando lo fai è un vero dolore se vengono mischiate insieme.

Modifica: aggiungerò che la tua implicazione che le clausole "where" nel codice di accesso ai dati sono un problema aziendale non è corretta. Il livello dati esiste per soddisfare le esigenze aziendali. I dati possono essere ritagliati e serviti in un numero infinito di modi, alcuni più utili di altri. Spostare una condizione dal livello aziendale al livello dati significa semplicemente che la richiesta è abbastanza comune da essere inclusa nei modi che sono forniti in modo utile fuori dalla scatola. Prevenire i nuovi ordini quando gli ordini attivi esistenti superano $ X è una decisione aziendale.

    
risposta data 04.07.2015 - 00:35
fonte
1

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

C'è una risposta breve a questo:

a) Il codice, che viene utilizzato per aprire una connessione a un DB, per recuperare i dati, fare una mappatura OR ecc. è chiamato 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;
 }

Esempio tratto da MSDN

b) Codice, che viene utilizzato per trasformare questi dati o conata le regole, quando recuperare questi dati si chiama business logic

Entrambe sono diverse responsabilità e vengono solitamente implementate in diversi livelli dell'applicazione:

a) In un livello a volte chiamato service-layer si trova la logica, quando recuperare il tipo di dati e come questi dati sono trattati alias business logic

b) Nel caso in cui stia implementando il schema del repository : questo è il luogo in cui 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).

No. È data access code , recupera i dati in modo pertinente per la logica aziendale.

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?

Nessuno dei due metodi contiene business logic . In realtà è solo access code . Il motivo per cui filtri i dati come fai tu è guidato da preoccupazioni aziendali, ma questo non li rende di per sé 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.

Forse dovresti pensare alla tua definizione di business logic . Questi pattern non sono in alcun modo anti-patterns , questi pattern consentono una chiara separazione delle preoccupazioni.

    
risposta data 04.07.2015 - 09:34
fonte
0

Mi sembra che manchi solo una definizione di classe.
Dichiara una classe CustomerOrders con il metodo GetOrdersTotal .
È un puro oggetto aziendale. Non esiste una tabella del genere nel db. Comprende un DAO Order e applica regole aziendali su di esso (ordine attivo, filtro per ID cliente).
Quindi, OrderRepository è il tuo DAL e CustomerOrders è il tuo BL

    
risposta data 04.07.2015 - 19:48
fonte

Leggi altre domande sui tag