Struttura del progetto: dove mettere la logica aziendale

5

Prima di tutto, non sto chiedendo da dove viene la logica aziendale. Questo è stato chiesto prima e la maggior parte delle risposte che ho letto concordano nel fatto che appartiene al modello:

Dove mettere la logica aziendale nella progettazione MVC?
Quanta logica di business dovrebbe esistere nel livello controller?
Quanto è accurato" La logica aziendale dovrebbe essere in un servizio, non in un modello "?
Perché mettere la logica del business nel modello? Cosa succede quando dispongo di più tipi di archiviazione?

Tuttavia le persone non sono d'accordo nel modo in cui questa logica dovrebbe essere distribuita tra le classi. Sembra che esistano tre correnti principali di pensiero:

  1. Modello grasso con business logic all'interno delle classi entity
  2. Modello anemico e logica aziendale nelle classi "Servizio".
  3. Dipende.

Li trovo tutti problematici.

La prima opzione è ciò a cui la maggior parte dei Fowlerite si attengono. Il problema con un modello grasso è che a volte una funzione di logica aziendale non è solo legata a una classe e utilizza invece una serie di altre classi. Se, ad esempio, stiamo sviluppando un negozio web, dovrebbe esserci una funzione che calcola il totale di un ordine. Potremmo pensare di inserire questa funzione nella classe Order, ma ciò che accade in realtà è che la logica deve utilizzare classi diverse, non solo i dati contenuti nella classe Order, ma anche nella classe User, nella classe Session e forse nella Tax. classe, classe del Paese o Giftcard, pagamento, ecc. Alcune di queste classi potrebbero essere composte all'interno della classe dell'ordine, ma altre no. Scusate se l'esempio non è molto buono, ma spero che capiate cosa intendo. Mettendo una tale funzione all'interno della classe dell'Ordine si romperebbe il principio di responsabilità singola, aggiungendo dipendenze non necessarie. La logica di business sarebbe dispersa tra le classi di entità, rendendola difficile da trovare.

La seconda opzione è quella che di solito seguo, ma dopo molti progetti sono ancora in dubbio su come denominare la classe o le classi che mantengono la logica aziendale. Nella mia azienda di solito sviluppiamo app con funzionalità offline. L'utente è in grado di eseguire transazioni intere offline, quindi tutte le regole di convalida e di business devono essere implementate nel client, e di solito c'è un thread in background che si sincronizza con il server. Quindi di solito abbiamo le seguenti classi / pacchetti in ogni progetto:

  • Modello dati (DTO)
  • Livello di accesso ai dati (Persistenza)
  • Livello dei servizi Web (di solito una classe per WS e un metodo per metodo WS).

Ora per la logica aziendale, qual è l'approccio standard? Una singola classe con tutta la logica? Classi multiple? (in tal caso, quali criteri vengono utilizzati per distribuire la logica su di essi?). E come dovremmo nominarli? FooManager? FooService? (So che l'ultimo è comune, ma nel nostro caso è una cattiva denominazione perché il layer WS di solito ha classi chiamate FooWebService).

La terza opzione è probabilmente quella giusta, ma è anche priva di qualsiasi informazione utile.

Per riassumere:

  • Non mi piace il primo approccio, ma accetto che non sarei stato in grado di comprendere pienamente lo Zen di esso. Quindi, se difendi i modelli grassi come unica e universale soluzione, ti invitiamo a pubblicare link che spieghino come farlo nel modo giusto.
  • Mi piacerebbe sapere quali sono le convenzioni standard di design e denominazione per il secondo approccio nelle lingue OO. Nomi di classi e struttura del pacchetto, in particolare. Sarebbe anche utile se potessi includere collegamenti a progetti Open Source che mostrano come è fatto.

Grazie in anticipo.

    
posta Mister Smith 20.08.2014 - 10:16
fonte

1 risposta

6

Penso che tu abbia sbagliato Fowler, sta sostenendo 3, non 1 (vedi link ). Nota che non sta parlando di "logica di business all'interno delle classi di entità", sta parlando di "business logic all'interno delle classi dominio ". E gli oggetti di servizio sono oggetti di dominio.

Nell'esempio sopra riportato: se è necessario calcolare il totale degli ordini, perché non creare una classe di servizio "OrderTotalCalculator"? Assegna un nome alla classe per il suo scopo (e non OrderService o OrderManager, che in realtà nascondono lo scopo).

Hai già menzionato un criterio da solo per quando introdurre una tale classe di servizio, e quando la logica di business può rimanere all'interno delle entità: quando "un gruppo di altre classi" è coinvolto, allora la collocazione della logica in un'entità specifica probabilmente non è il miglior design. Hai anche menzionato il principio della responsabilità unica, quindi lasciati guidare da questo.

Tuttavia, questo non porta necessariamente all'opzione 2 - poiché per esperienza mi sono in genere sufficienti operazioni commerciali per le quali un'entità può assumersi la piena responsabilità per se stessa, senza introdurre una classe di servizio extra per ogni operazione. Questo in genere porterà a classi di entità magre (ma non anemiche)

The third option is probably the right one, but it is also devoid of any useful info.

Sì, probabilmente è quello giusto, ma cosa intendi con "è privo di informazioni utili"? Ti manca un manuale di istruzioni su questo? Lo sviluppo del software è un processo di progettazione, non come lavorare in una catena di montaggio. Pertanto, prendere le giuste decisioni di progettazione non è sempre facile e richiede molta esperienza. E la denominazione delle cose è in realtà una delle attività più difficili .

    
risposta data 20.08.2014 - 11:12
fonte