Oh-keeey.
Cosa ti stai sbagliando del modello ..
Devi capire che il "Modello" in MVC non è un oggetto concreto o una classe. Invece è uno dei due livelli principali dell'applicazione:
Il livello del modello - contiene la "logica aziendale", è dove si trova la maggior parte delle "parti interessanti"
Il livello di presentazione - si occupa dell'interfaccia attraverso la quale l'utente può interagire con questa "logica aziendale"
Note: as you might already notice, it is perfectly alright to have several presentation layers in parallel. Though it's rare "in the wild".
Il tuo livello di presentazione (costituito da viste e controllori) interagisce con il livello del modello tramite i servizi . Detti servizi contengono l'interazione tra oggetti dominio e data mapping . Questa parte va sotto il nome di "logica dell'applicazione".
For example: if you had a service Library
, it manipulate and the exchange between User
and Book
instance and pass them to different data mappers for persistence. The service doesn't really care how the isValid()
method works internally for for the User
instance. Neither does it cares where the user is saved, when you call mapper.store(user)
.
Gli oggetti del dominio nel livello del modello sono la rappresentazione in codice di "Modello dominio" (per sapere di cosa si tratta, vedi questo libro ). Fondamentalmente, conterranno tutte le regole, le condizioni e le idee aziendali su cui si basa l'applicazione.
E il terzo gruppo principale di strutture all'interno del livello del modello sono in genere mapper di dati. Va la logica della persistenza. È dove il tuo codice CRUD esiste realmente. E parte della logica di persistenza sono i controlli di integrità dei dati. Se, quando si inserisce un nuovo indirizzo e-mail in una tabella, si ottiene un'eccezione relativa alla violazione del vincolo UNIQUE
, i mapper dei dati sono dove lo gestisci. Sia che tu lo faccia impostando uno stato di errore sull'oggetto dominio che stai manipolando o kickando / restituendo un codice di errore al servizio, è una tua preferenza (mi piace il precedente approccio).
Note: mappers can persist data in any medium that like: sql, nosql, files, remote rest api, /dev/null or crystalline fairy dust. And, if you make sure that the all have same public interface, you can use multiple data mappers on the same domain object. That would let you populate the infamous User
instance from sql, cache and session. Simply by passing it to three different mappers with mapper->fetch(user)
calls
Quindi .. dove sono i controllori in tutto questo
I controller, secondo lo schema MVC, hanno una responsabilità molto specifica: alterare lo stato del livello del modello e (in rari casi) la vista corrente. Questo.
I controllori non sanno nulla di CRUD. I controllori non ricevono dati dal livello del modello. I controller non inizializzano o eseguono il rendering delle viste. Niente di tutto ciò.
Note: there are edge cases, where in desktop applications (or in situations when, within application's lifetime, there are multiple users interacting with it ... not applicable to web) the controller can observe model layer for changes. And, based on specific change, unlock additional functionality for same user's interaction. I have never seen it in practice.
Questo significa anche che le tue viste devono essere oggetti reali e non solo modelli stupidi, perché, dal momento che il controllore non sta prelevando alcun dato dal livello del modello, le viste devono decidere quali informazioni hanno bisogno e chiederle da sé.
Queste visualizzazioni completamente implementate di solito destreggiano tra più modelli / layout e oggetti di presentazione . Dall'alta orbita la volontà assomiglia ai servizi, poiché la manipolazione di modelli e oggetti di presentazione assomiglia vagamente all'interazione tra i mappatori di dati e gli oggetti del dominio.
i miei 2 centesimi