Domanda

Per prima cosa, prima che qualcuno urla vittima, ho avuto un momento difficile che riassume in un semplice titolo. Un altro titolo avrebbe potuto essere "Qual è la differenza tra un modello di dominio e il modello MVC?" o "che cosa è un modello?"

Concettualmente, capisco un modello da dati utilizzati dai punti di vista e di controllo. Oltre a ciò, sembra che ci sia una grande quantità di opinioni diverse su ciò che rende il modello. Che cosa è un modello di dominio, contro un modello di applicazione, vs un modello di vista, contro un modello di servizio, ecc ..

Per esempio, in una recente interrogazione ho chiesto circa il modello repository, mi è stato detto a bruciapelo che il repository è parte del modello. Tuttavia, ho letto altri pareri che il modello dovrebbe essere separata dal modello di persistenza e lo strato logica di business. Dopo tutto, non è il modello Repository dovrebbe disaccoppiare il metodo di persistenza di cemento dal modello? Altre persone dicono che c'è una differenza tra il modello di dominio e il modello MVC.

Facciamo un semplice esempio. L'AccountController che è incluso con il progetto predefinito MVC. Ho letto diversi pareri che il codice del conto incluso è di cattiva progettazione, viola SRP, ecc .. ecc .. Se si dovesse progettare un "proprio" modello di iscrizione per un'applicazione MVC, quale sarebbe?

Come vi separare i servizi ASP.NET (provider di appartenenza, provider di ruoli, ecc ..) dal modello? Se non sei ancora a tutti?

Il mio modo di vedere, il modello dovrebbe essere "pura", magari con la logica di convalida .. ma dovrebbe essere separata da regole aziendali (diversi convalida). Per esempio, diciamo che si dispone di una regola aziendale che dice che qualcuno deve essere inviato via email quando viene creato un nuovo account. Che non appartiene in realtà nel modello, a mio avviso. Allora, dove appartiene?

Chiunque si preoccupa di gettare luce su questo problema?

È stato utile?

Soluzione

Il modo in cui l'ho fatto - e non sto dicendo che è giusto o sbagliato, è quello di avere mio punto di vista e poi un modello che si applica al mio punto di vista. Questo modello ha solo ciò che è rilevante per mio punto di vista - tra cui le annotazioni di dati e regole di validazione. Il controller ospita solo la logica per la costruzione del modello. Ho un livello di servizio che ospita tutta la logica di business. I miei controllori chiamano il mio livello di servizio. Al di là di ciò che è il mio livello di repository.

I miei oggetti di dominio sono alloggiati separatamente (nel proprio progetto, in realtà). Hanno la loro annotazioni di dati e le regole di validazione propria. Il mio repository convalida gli oggetti nel mio dominio prima di salvarle nel database. Perché ogni oggetto nei miei eredita dominio da una classe base che ha costruito in validazione, mio ??repository è generico e convalida tutto (e richiede eredita dalla classe base).

Si potrebbe pensare che avere due serie di modelli è la duplicazione del codice, ed è in una certa misura. Ma, ci sono casi perfettamente ragionevoli in cui l'oggetto di dominio non è appropriato per la vista.

Caso in questione è quando si lavora con le carte di credito - devo richiedere una CVV durante l'elaborazione di un pagamento, ma non riesco a memorizzare il CVV (si tratta di una multa di $ 50.000 a farlo). Ma, anche io voglio che tu sia in grado di modificare la carta di credito - il cambiamento di indirizzo, il nome o la data di scadenza. Ma non si ha intenzione di darmi il numero o il CVV quando si modifica, e io di certo non ho intenzione di mettere il vostro numero di carta di credito in formato testo sulla pagina. Il mio dominio ha questi valori necessari per il salvataggio di una nuova carta di credito perché li si dà a me, ma la mia modifica modello non include anche il numero di carta o CVV.

Un altro vantaggio di tanti strati è che se architettato correttamente, è possibile utilizzare StructureMap o in un altro contenitore CIO e sostituire pezzi senza un impatto negativo sulle vostra applicazione.

A mio parere, il codice di controllo dovrebbe essere il codice mirato solo alla vista. Mostrare questa, nascondere che, etc. Il livello di servizio dovrebbe ospitare la logica di business per la vostra applicazione. Mi piace avere tutto in un unico luogo in modo che sia facile cambiare o modificare una regola aziendale. Lo strato repository dovrebbe essere relativamente muto - privo di logica di business e interrogare i vostri dati e restituire gli oggetti del dominio. Separando i modelli vista dal modello di dominio, si ha molta flessibilità di più quando si tratta di regole di validazione personalizzati. E significa anche che non c'è bisogno di scaricare ogni pezzo di dati nel vostro vista in campi nascosti e spingerlo avanti e indietro tra il client e server (o ricostruirlo sul backend). Il vostro modello vista sarà quindi ospitare solo le informazioni rilevanti per la vista - e può essere personalizzato per avere Caccio per la logica vista o conteggi o enumerazioni in modo che la vista in sé non è ingombra di istruzioni logiche complesse come

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

Mentre tutto sembra sparsi e più strati, che ha uno scopo per essere architettato questo modo. E 'perfetto? non proprio. Ma io preferisco ad alcuni disegni del passato di chiamare repository dal controller e con la logica di business mescolato nel controller, repository, e il modello.

Altri suggerimenti

I troppo spesso chiesto come esattamente gli elementi MVC si inseriscono in una struttura di un'applicazione web tradizionale, dove si ha una vista (pagine), i controllori, i servizi e gli oggetti di dati (Model). Come hai detto, ci sono molte versioni di questo.

Credo che la confusione esiste a causa del sopraindicato, l'architettura ampiamente accettata, che utilizza il "modello di dominio anemico" (presunto) modello -Anti. Non voglio entrare in molto particolari circa la "anti-patternness" del modello di dati anemico (si può guardare uno sforzo di miniera per spiegare le cose qui (basato su Java, ma rilevante per qualsiasi lingua)). Ma in breve, ciò significa che il nostro modello tiene solo i dati, e la logica di business è collocato in servizi / manager.

Ma ammettiamo pure che abbiamo dominio Driven Architecture , ed i nostri oggetti di dominio sono la strada essi dovrebbero essere - avere sia logica di stato e di business. E in questa prospettiva dominio-driven cose vengono a posto:

  • la vista è l'interfaccia utente
  • le arricciature controllore ingressi dell'interfaccia utente, metodi invoca sul modello, e restituisce una risposta alla UI
  • il modello è i nostri componenti aziendali -. Tiene i dati, ma anche avere la logica di business

credo che risponde alle vostre domande principali. Le cose si complicano quando si aggiungono alcuni più strati, come lo strato repository. E 'spesso suggerito che dovrebbe essere invocato dalla logica di business collocato nel modello (e quindi ogni oggetto dominio ha un riferimento a un repository). Nel mio articolo che ho linkato io sostengo che questa non è una pratica del tutto migliore. E che in realtà non è una brutta cosa avere un livello di servizio. Tra l'altro, Domain-Driven Design non esclude il livello di servizio, ma si suppone che sia 'sottile', e solo coordinando gli oggetti di dominio (quindi nessuna logica di business lì).

Per il modello di dati anemico paradigma, che è ampiamente adottato (nel bene e nel male), il modello sarebbe sia il livello di servizio e gli oggetti di dati.

A mio parere,

Modello -

Qualora non contiene la logica di business, dovrebbe essere pluggable (WCF come scenario). Viene utilizzato per legare per vederlo così, dovrebbe avere proprietà.

Business Logic -

Si deve essere posizionato ad "Layer Servizi di dominio", è strato separato del tutto. Inoltre, aggiungerà più uno strato qui "Application Services".

App Services parla a livello di Servizi di dominio per applicare la logica di business e poi, infine, restituire il modello.

Quindi, Controllore chiederà Application Service per il modello ed il flusso andrà come,

    Controller->Application Services(using domain services)->Model

Il pattern MVC e il quadro Asp.net non fa alcuna distinzione su ciò che il modello dovrebbe essere.

propri esempi di Ms includono la persistenza classi del modello. La tua domanda sull'appartenenza essere nel modello. Questo dipende. Sono classi nel modello di proprietà di qualcosa? C'è un legame tra chi accede e quali dati vengono visualizzati? C'è il filtraggio di una parte dei dati di un sistema di autorizzazioni che è modificabile? È CHI ultimo aggiornamento o modifica una parte oggetto del vostro dominio come in qualcuno ha bisogno di vedere altro o qualcosa per il supporto back-end?

L'esempio e-mail è anche dipende. Sei familiarità con eventing dominio o eventing in particolare? Avete un servizio separato per inviare messaggi di posta elettronica? È l'atto di inviare una parte e-mail del tuo dominio o è un livello di applicazione preoccupazione al di fuori della portata del vostro sistema? Ha la necessità di interfaccia utente per sapere se una e-mail è stato inviato con successo o no? Fare le email che non riescono a trasmettere tentativi bisogno? Ha il contenuto della necessità di posta elettronica inviato da memorizzare per esigenze tecniche o di servizio al cliente?

Questi tipi di domande sono eccessivamente ampia e soggettiva, ma sto rispondendo in modo da voi e tutti coloro che vi hanno votato up può capire questo.

I tuoi requisiti / tempistiche / tutte le risorse di sfiato nell'architettura del sistema. Anche il modello di ricavi può avere un effetto. Dovete anche considerare il modello che si sono riprese per. DDD è molto diverso da applicazioni persistenza-as-modello e tutto lo slop in mezzo ci sono valide anche per alcune applicazioni. Stai girando per testare l'applicazione? Tutto questo ha un effetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top