Perché inserire la logica aziendale nel modello? Cosa succede quando ho più tipi di archiviazione?


70

Ho sempre pensato che la logica aziendale dovesse essere nel controller e che il controller, poiché è la parte "centrale", rimane statico e che il modello / vista deve essere bloccato tramite interfacce. In questo modo è possibile modificare la logica aziendale senza influenzare nient'altro, programmare più modelli (uno per ciascun database / tipo di archiviazione) e una dozzina di visualizzazioni (ad esempio per piattaforme diverse).

Ora ho letto in questa domanda che dovresti sempre inserire la logica di business nel modello e che il controller è profondamente connesso con la vista.

Per me, questo non ha davvero senso e implica che ogni volta che voglio avere i mezzi per supportare un altro database / tipo di archiviazione devo riscrivere il mio intero modello inclusa la logica aziendale.

E se voglio un'altra vista, devo riscrivere sia la vista che il controller.

Qualcuno può spiegare perché questo è o se ho sbagliato da qualche parte?

Risposte:


69

La risposta di ElYusubov in gran parte la risolve , la logica del dominio dovrebbe andare nel modello e la logica dell'applicazione nel controller.

Due chiarimenti:

  • Il termine logica di business qui è piuttosto inutile, perché è ambiguo. La logica di business è un termine generico per tutte le logiche che interessano gli uomini d'affari, separandole da semplici tecnicismi come il modo di archiviare elementi in un database o come renderli su uno schermo. Sia la logica di dominio ("un indirizzo email valido assomiglia a ...") sia i flussi di lavoro / i processi aziendali ("quando un utente si iscrive, chiede il suo indirizzo email") sono considerati logica aziendale, con il primo chiaramente appartenente al modello e quest'ultimo è la logica dell'applicazione che va nel controller.
  • MVC è un modello per mettere roba su uno schermo e permettendo all'utente di interagire con esso, non specifica di archiviazione a tutti . La maggior parte dei framework MVC sono framework full stack che vanno oltre il semplice MVC e ti aiutano a memorizzare i tuoi dati, e poiché i dati che dovrebbero essere archiviati di solito si trovano nel modello, questi framework ti offrono modi convenienti per archiviare il tuo modello- dati in un database, ma ciò non ha nulla a che fare con MVC. Idealmente, i modelli dovrebbero essere indipendenti dalla persistenza e il passaggio a un diverso tipo di archiviazione non dovrebbe influenzare affatto il codice modello. Le architetture complete hanno uno strato di persistenza per gestirlo.

4
La maggior parte dei framework MVC mescola tutti gli elementi di archiviazione / database nel modello per semplificare l'archiviazione dei modelli (spesso aumentando la classe del modello dei framework). Questa è probabilmente la fonte di confusione. Tecnicamente, il codice modello che scrivi dovrebbe essere il modello reale (livello di dominio), mentre il codice fornito dal framework dovrebbe occuparsi della memoria (livello di persistenza). Ad esempio, qualcosa come User.find (...) (con l'utente come modello) funziona perché il framework ha implementato il modello di repository come parte del modello.
Waquo,

3
View-Controller-Model-Storage è il principio generale (sebbene la relazione tra M, V e C dovrebbe essere visualizzata come un triangolo). Quando il tuo framework mescola lo storage nel loro "modello", funziona in questo modo: View-Controller- (il modello eredita lo storage dal framework).
Waquo,

2
View-Controller-Model-Storage è piuttosto grezzo, perché non dovrebbe essere piatto. Ad esempio, quando un controller fa qualcosa come User.find (...) per ottenere un modello, chiede direttamente al livello di archiviazione anziché passare attraverso il livello di dominio.
Waquo,

2
Nelle architetture con stratificazione più accurata, sarebbe qualcosa come UserRepository.find (). Per "modello" intendevo la classe "modello" fornita dal framework, da cui erediti. L'oggetto User restituito da User.find () è un modello di un utente, nel senso che qualcuno ha modellato ciò che è un utente, come si comporta un utente ...
Waquo

1
La logica aziendale di @flipdoubt è qualsiasi logica che dovrebbe essere mantenuta invariata se si esegue il porting da mvc per dire un'app uwp.
Andy,

23

Tu e gran parte del mondo della programmazione sembra fraintendere quali sono i ruoli delle parti MVC. In breve, sono:

Modello = logica di dominio

Visualizza = logica di output

Controller = logica di input

Ciò significa che il modello è responsabile dell'intera logica aziendale: tutto ciò che è legato al disegno di widget su uno schermo, alla guida di una stampante, alla trasmissione di dati come HTML, all'analisi delle richieste HTTP, ecc. Ecc. Non appartiene al modello.

Tuttavia, molti dei moderni quadri cosiddetti "MVC" non eseguono affatto MVC o etichettano erroneamente le loro parti. Molto spesso, ciò che viene chiamato "modello" è il livello di persistenza del modello, mentre la logica aziendale si trova in quello che chiamano "controller"; il controller effettivo di solito è solo un punto di ingresso centrale con una tabella di routing e un po 'di codice nei singoli "controller" per inviare l'input che ricevono ai processi aziendali corretti. Ciò che questi framework chiamano "view" è in realtà un po 'di tutto: un po' di logica di presentazione (View), un po 'di input management e validazione (Controller), e un po' più di business logic (Model). La parte del leone della vista reale è generalmente chiamata "template".

Potresti anche voler leggere sull'architettura multilivello; dove MVC è un po 'unidirezionale (il flusso è Controller -> Modello -> Visualizza), Multi-Tier è una cosa a due vie (Presentazione -> Logica -> Dati -> Logica -> Presentazione), e parecchi i framework che fingono di fare MVC eseguono in realtà tre livelli, rietichettando Presentation to View, Logic to Controller e Data to Model.


2
Credo che tu abbia travisato il Modello ("Modello = logica di dominio"), a mio avviso è più una nave per popolazione con dati, che viene quindi reso usando una Vista, nella forma più pura del modello MVC. Certo in casi d'uso davvero semplici puoi trattarlo come la "logica di dominio", ma garantirei che la maggior parte dei sistemi che valga la pena esistere supererebbe molto rapidamente. Meglio dividere la "logica di dominio" in un livello / classe separata, ad esempio un livello di servizio.
A. Murray,

@ A.Murray: Ovviamente il Modello non deve essere un blocco monolitico di codice e la sua separazione in persistenza, strutture di dati e logica di dominio di solito ha molto senso. Tuttavia, MVC raggruppa queste tre preoccupazioni nel Modello. In ogni caso, quando i controller e le viste contengono una logica di dominio, non è più un vero MVC.
tdammers,

@tdammers, mi piace l'ordine della tua risposta e la sua attenzione alla logica. A tuo avviso, dove appartengono i problemi di applicazione come la persistenza e l'elaborazione delle transazioni? Sembra che MVC dovrebbe essere un acronimo di quattro lettere come MVCS in cui la S è per servizio.
capovolgere il

15

Per isolare veramente la logica aziendale e renderla separata dall'infrastruttura del livello di presentazione, dovrebbe essere incapsulata dai servizi dell'applicazione. L'architettura MVC è un modo per implementare il livello di presentazione e dovrebbe rimanere in tale ambito, delegando tutta la logica aziendale a questi servizi applicativi. Pensa ai modelli di vista come adattatori tra la vista e i dati che devono essere visualizzati e o letti. Il controller media l'interazione tra modelli di vista, viste e servizi applicativi che ospitano la logica aziendale.

I servizi applicativi implementano casi d'uso aziendali e sono disaccoppiati dal livello di presentazione, sia esso MVC o qualcos'altro. A loro volta, i servizi applicativi possono ospitare script di transazione o una progettazione guidata dal dominio .

Per l'archiviazione, il servizio applicativo può fare riferimento a un repository o qualsiasi astrazione di un meccanismo di persistenza. Diverse implementazioni possono essere supportate astrattando l'accesso ai dati in un'interfaccia. In genere, queste astrazioni perdono e sono solo parzialmente trasportabili attraverso le implementazioni ed è spesso un tentativo inutile di raggiungere la piena portabilità.

AGGIORNARE

Il mio suggerimento si basa sull'architettura esagonale . In un'architettura esagonale, il tuo modello di dominio (logica aziendale) è al centro. Questo nucleo è incapsulato da servizi applicativi che fungono da facciata . I servizi applicativi sono semplici classi che hanno metodi corrispondenti ai casi d'uso nel tuo dominio. Per una discussione approfondita sui servizi applicativi, dai un'occhiata ai servizi in Domain-Driven Design . L'esempio di codice contiene un PurchaseOrderServiceche è un servizio applicativo per un dominio di acquisto. (Si noti che un servizio applicativo non implica l'uso di una progettazione guidata dal dominio.)

In un'architettura esagonale, un livello di presentazione MVC è un adattatore tra il modello di dominio (logica aziendale) e una GUI. Il modello di dominio non è a conoscenza del livello di presentazione, ma il livello di presentazione è a conoscenza del modello di dominio.

Questa soluzione ha sicuramente parti mobili rispetto a una soluzione che pone la logica di business nel controller e dovresti valutare gli svantaggi e i vantaggi. Il motivo per cui lo suggerisco è perché preferisco mantenere la logica aziendale disaccoppiata dal livello di presentazione al fine di combattere la complessità. Questo diventa più importante man mano che l'applicazione cresce.


Sembra che tu stia descrivendo un bastardo di MVC e MVVM che ha sia controller che modelli di visualizzazione. Inoltre, penso che l'architettura che stai descrivendo possa essere un po 'pesante per le esigenze di OP.
Waquo,

ad essere sincero, mi piace di più la risposta di Waquo. Principalmente perché non ho idea di cosa intendi con "servizi applicativi". Potresti spiegare quel termine? GoogleFU non funziona qui come sembra.
Steffen Winkler,

1
@Waquo Sono d'accordo sul fatto che l'architettura proposta potrebbe essere eccessiva, tuttavia dovrebbe essere considerata. Non ho menzionato MVVM, che è semplicemente un altro modo per implementare un livello di presentazione. I servizi applicativi si applicano indipendentemente dal fatto che si utilizzi MVC o MVVM e nulla di ciò che ho suggerito indica una combinazione dei due.
eulerfx,

1

Dipende da cosa intendi per logica di business. Qualsiasi "logica" che dia significato ai contenuti del modello dovrebbe essere nel modello. Nella domanda collegata, la risposta più votata sembra definire la "logica di business" come qualsiasi cosa relativa ai dati; questo ha senso dal punto di vista che i dati di un'azienda sono affari suoi!

Una volta ho visto un esempio del creatore di Rails (penso) che stava succedendo esattamente questo, senza inserire la "logica aziendale" nel modello. Il suo esempio era una classe di controller e un metodo per la registrazione e il login dell'app: una password fornita in testo normale veniva crittografata prima di essere inserita o interrogata nel modello (un database).

Non riesco a pensare a un esempio migliore di qualcosa che non è la logica del controller e che appartiene direttamente al modello.

Il modello potrebbe essere un'interfaccia per una miriade di archivi dati, alleviando i problemi di portabilità. È qui che si potrebbe trovare confusione sul fatto che l'interfaccia del modello sia in realtà il "controller".

In generale, il controller collega il modello e la vista (che sono la carne e le patate dell'app.) Nello sviluppo di Cocoa può essere semplicistico al punto in cui il controller viene gestito tramite la GUI XCode (oggetti controller e associazioni).

La sezione "Design Patterns" di GoF su MVC, liberamente citata:

La triade di classi MVC viene utilizzata per creare interfacce utente in Smalltalk-80. Il modello è l'oggetto dell'applicazione, la vista è la presentazione dello schermo e il controller definisce il modo in cui l'interfaccia utente reagisce all'input dell'utente. MVC disaccoppia le viste e i modelli stabilendo un protocollo di sottoscrizione / notifica tra di loro. Il diagramma seguente mostra un modello e tre viste. Abbiamo lasciato fuori i controller per semplicità.

MVC si basa sulle interfacce utente. L'attenzione si concentra sul modello e sulla vista: definizione e visualizzazione dei dati. Nota il "protocollo di iscrizione / notifica": è qui che entra in gioco il tuo controller. Puoi creare tutte le visualizzazioni che desideri; fintanto che aderiscono al protocollo non dovrai mai toccare il modello o il controller.

Se parli in particolare dello sviluppo web, IMHO molti framework Web popolari sono veloci e sciolti con il termine MVC e le sue definizioni dei componenti.


Sono uno sviluppatore C # / Java (solo pochi progetti lì). Sembra che ho capito male cosa fa il modello. Mettere la "logica aziendale" nel controller era davvero solo un effetto secondario (il mio treno di pensieri è andato "bene, ho il modello per i dati (leggi: connessione al database / archiviazione), quindi la mia logica aziendale deve entrare nel controller perché Devo applicarlo prima di archiviare i dati nel database ". Devo solo spostare tutto di un livello dal controller. In realtà, ciò risolve un problema che ho attualmente (supporto MySQL e MSSQL in un programma)
Steffen Winkler

0

Perché non introdurre un livello di servizio?

Quindi il controller sarà snello e più leggibile, quindi tutte le funzioni del controller saranno azioni pure.

È possibile scomporre la logica aziendale in base alle esigenze all'interno del livello di servizio. La riusabilità del codice è migliore e non vi è alcun impatto su modelli e repository.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.