Quanto è accettabile mantenere la logica aziendale al di fuori delle entità (in classi di servizio separate)?

7

Ci è stato insegnato che gli oggetti sono cose autonome con dati e comportamenti e quindi dovrebbero avere metodi che agiscano sui loro attributi. Ma ci sono diverse situazioni in cui questo accoppiamento tra entità e il loro comportamento non è osservato:

  • I framework di entità (come .NET con POCO e Enterprise Java con entità POJO) stabiliscono che le operazioni di CRUD / persistenza / ricerca devono essere eseguite da gestori di entità esterne (e repository) e non dalle entità stesse, ovvero abbiamo codice entityManager.save(entity) e non entity.save() ;
  • I motori di regole aziendali sono gli esempi più visibili di separazione della logica di business dalle entità: le regole aziendali formano un codice completamente diverso (anche in lingue diverse) dalle entità. Per esempio. JBoss Drools o IBM ILOG o altri motori di regole. Il paradigma della regola aziendale può essere utilizzato per estrapolare la programmazione OO - in OO consideriamo dati e metodi, ma nel web semantico possiamo considerare ontologie e regole logiche / commerciali che agiscono su ABox o TBox di ontologie - due lingue completamente diverse e sistemi di ragionamento.
  • Il calcolo distribuito prevede l'uso della serializzazione e della deserializzazione di oggetti e la comunicazione di tali oggetti attraverso la rete - per questo abbiamo XML, formati binari nativi o JSON. Solitamente, solo i dati vengono comunicati tramite la rete e la logica aziendale viene mantenuta su un unico livello e non esiste una tecnologia per spostare la logica di business su reti e piattaforme, ad es. non vi è alcuna traduzione automatica e comunicazione della logica aziendale quando le entità Java sono tradotte in oggetti JSON ed esposte tramite API REST al frontend Angular 2. La logica aziendale di solito è tenuta da un lato (ad es. In Java).
  • Si dice che il modello di dominio OO dovrebbe riflettere / modellare il mondo reale. E a volte gli oggetti del mondo reale non hanno una logica aziendale al loro interno. Per esempio. ci sono concetti sui calcolatori, ad es. calcolatori delle imposte, calcolatori salariali ecc. Pertanto scriviamo calculator.recalcTaxes(invoice) e non invoice.recalcTaxes . Il primo approccio ci consente di applicare diversi calcolatori in diversi casi = per es. attraverso le legislazioni. Non siamo costretti a costruire una gerarchia di eredità complessa semplicemente perché ci sono diversi metodi di business, semplicemente applichiamo servizi / calcolatori aziendali diversi agli stessi dati.

Considerando questi argomenti che separano la logica di business da dati / entità - quanto è accettabile rendere questa separazione come la regola generale di progettazione per il mio progetto di software aziendale? Quali sono gli argomenti contro la separazione della logica aziendale dai dati?

    
posta TomR 28.12.2016 - 21:29
fonte

3 risposte

5

Credo che il problema a cui ti riferisci sia collegato alle caratteristiche di una singola classe e al livello di scomposizione della classe stabilito per un problema considerato. Ciascuno dei tuoi esempi sembra ragionevole tenendo conto delle caratteristiche della classe. D'altra parte, ci sono molti scenari in cui i dati sono legati alla logica. In tal caso si chiama piuttosto comportamento di classe rispetto alla logica aziendale.

Ciascuno di questi deve essere considerato separatamente tenendo conto almeno del seguente:

  • la logica aziendale rappresenta la logica esterna o il comportamento della classe interna?
  • la classe rappresenta il modello?
  • qual è il livello di complessità logica?
  • qual è la probabilità che la logica aziendale cambierà?
  • qual è la probabilità che verranno applicate nuove regole di business logic all'oggetto?
  • è classe esposta all'ambiente esterno?
  • è una logica di classe distribuita su livelli nell'approccio n-tier?

Uncle Bob ha introdotto alcuni principi di progettazione orientata agli oggetti denominati SOLID . Uno dei principi, Principio di Responsabilità Unica (SRP) descrive esattamente a cosa ti riferisci:

a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class)

Questa è la regola generale. Cosa è importante (consigliato anche da Martin), il principio dovrebbe essere utilizzato solo negli scenari che la classe è considerata nella catena del cambiamento / ha un motivo per cambiare . In altri casi, l'uso del principio può aumentare la complessità del codice ...

Un breve esempio: crei (o usi) una classe chiamata List che contiene il modello (Items) e il comportamento (Add, Edit, Delete) piuttosto che due classi (ListContainer e ListManager). a causa della complessità non necessaria introdotta al problema che è un comportamento di classe 'interno'. Inoltre, il modo in cui la lista gestirà gli oggetti non cambierà mai.

    
risposta data 28.12.2016 - 22:34
fonte
4

Se si sta letteralmente parlando di business logic come in, è per un business e non per la logica di dominio in generale, trovo che molte entità abbiano una logica imposta da influencer esterni o dal contesto (Ti diamo uno sconto se. ..). Ecco perché la programmazione aziendale può essere così frustrante perché le cose possono sembrare arbitrarie. Le entità non sempre corrispondono al mondo reale, ma il mondo come l'azienda lo percepisce in circostanze diverse. C'è un solo cliente chiamato "Acme, Inc." ma dobbiamo avere due voci perché il nostro sistema consente solo a un addetto alle vendite di essere assegnato a loro, e abbiamo bisogno che ne abbiano due a causa del cugino di qualcuno yadda-yadda-yadda. Non ti preoccupare, non devi farlo sempre (come se ciò che conta), quindi sono sicuro che puoi programmare il computer per fare questa eccezione quando si calcolano i loro acquisti totali.

Negli Stati Uniti, se assumi un appaltatore, devi fornire loro un modulo fiscale 1099 se ti fatturano oltre $ 400. Questa regola non fa parte del contraente o anche di una particolare fattura, ma una regola fiscale esterna del governo che esamina l'insieme delle fatture per un determinato anno fiscale. Questa regola potrebbe persino fluttuare da un anno all'altro. Trattare con le organizzazioni non profit può presentare un'altra preoccupazione. Hai davvero bisogno di una sorta di tax.calculator per questo.

Quando non separi correttamente la tua logica, gli utenti possono iniziare a utilizzare le tue entità in modi che non avevi programmato, perché la logica di business è troppo legata all'entità. L'inserimento dei dati degli indirizzi dei clienti dovrebbe essere così semplice, ma hai mai visto: AddressLine3="c / o John Smith" perché l'app non distingue le consegne di lavoro dalle residenze private? Poiché non si dispone di una logica separata per la stampa delle etichette postali, gli utenti fanno di tutto per risolvere la mancanza di informazioni sull'indirizzo separato dalla logica di stampa dell'indirizzo.

Le regole aziendali tendono ad essere una combinazione di fattori e raramente vengono tagliate e asciugate per una data entità. Puoi mettere la logica in un'entità aziendale, ma penso che ti ritroveresti a smentire questo quando tutti finalmente identificheranno come le cose sono realmente fatte o saranno fatte.

    
risposta data 29.12.2016 - 00:24
fonte
1

how acceptable is to make this separation as the general rule of design for my project of business software?

Dipende dal paradigma che vuoi seguire. In pratica si descrive la programmazione procedurale (una serie di istruzioni agisce sui dati) rispetto alla programmazione orientata agli oggetti (un oggetto esegue un'unità di comportamento tramite la richiesta di altri oggetti che eseguono anche unità di comportamento).

Come ricorda Alan Kay, non esistono praticamente veri e propri sistemi / linguaggi orientati agli oggetti. Quindi non sorprende che i paradigmi di programmazione procedurale si introducano nelle lingue "OO" come hai elencato. Non direi che ciò significhi che quel paradigma procedurale è necessario, solo che spesso il pensiero procedurale (come lo chiama Dave West) è più facile quando si scrive codice. C'è un sacco di codice cosiddetto "object oriented" che non è in realtà orientato agli oggetti.

Personalmente sono un abbonato all'idea che se stai per seguire un paradigma procedurale dovresti usare un linguaggio procedurale (o le caratteristiche procedurali di un linguaggio che supporta sia procedurale che OO). Cercando di inserire codice procedurale in codice che stai cercando di rendere il più possibile orientato agli oggetti, puoi creare un po 'di confusione.

    
risposta data 29.12.2016 - 13:52
fonte