Potrebbe non essere la migliore idea considerare Rails come un punto fermo del modello di progettazione MVC. Detto framework è stato realizzato con alcune carenze intrinseche (l'ho elaborato in un post diverso ) e la comunità solo ora ha iniziato ad affrontare le ricadute. Potresti considerare lo sviluppo di DataMapper2 come il primo passo importante.
Qualche teoria
Le persone che danno quel consiglio sembrano essere afflitte da un malinteso abbastanza comune. Quindi consentitemi di iniziare chiarendo: Model, nel moderno design pattern MVC, NON è una classe o un oggetto. Il modello è uno strato.
L'idea centrale dietro il pattern MVC è Separation of Concerns e il primo passo in esso è la divisione tra il livello di presentazione e i livelli del modello. Proprio come il livello di presentazione si suddivide in controller (istanze, responsabili della gestione dell'input dell'utente), viste (istanze, responsabili della logica dell'interfaccia utente) e modelli / layout, così fa il livello del modello.
Le parti principali di cui è composto il livello del modello sono:
Oggetti di dominio
Conosciuto anche come entità di dominio, oggetti di business o oggetti modello (non mi piace quest'ultimo nome perché aggiunge solo confusione). Queste strutture sono ciò che la gente di solito chiama erroneamente "modelli". Sono responsabili del contenimento delle regole di business (tutta la matematica e la convalida per una specifica unità di logica del dominio).
Astrazioni di archiviazione:
Di solito implementato utilizzando il modello di mappatura dati (da non confondere con gli ORM , che hanno abusato di questo nome). Queste istanze di solito hanno il compito di archiviare e recuperare le informazioni negli oggetti del dominio. Ogni oggetto di dominio può avere diversi mappatori, proprio come esistono diverse forme di archiviazione (DB, cache, sessione, cookie, / dev / null).
Servizi:
Strutture responsabili della logica dell'applicazione (ovvero, interazione tra oggetti di dominio e interazione tra oggetti di dominio e astrazioni di archiviazione). Dovrebbero agire come l '"interfaccia" attraverso la quale il livello di presentazione interagisce con il livello del modello. Questo di solito è ciò che nel codice tipo Rails finisce nei controller.
Ci sono anche diverse strutture che potrebbero trovarsi negli spazi tra questi gruppi: DAO , unità di lavoro e archivi .
Oh ... e quando parliamo (nel contesto del web) di un utente che interagisce con l'applicazione MVC, non è un essere umano. L '"utente" è in realtà il tuo browser web.
E le divinità?
Invece di avere un modello monolitico e spaventoso con cui lavorare, i controller dovrebbero interagire con i servizi. I dati vengono passati dall'input dell'utente a un servizio specifico (ad esempio MailService
o RecognitionService
). In questo modo il controller cambia lo stato del livello del modello, ma viene eseguito utilizzando un'API chiara e senza interferire con le strutture interne (il che causerebbe un'astrazione che perde).
Tali modifiche possono causare una reazione immediata o influire solo sui dati richiesti dall'istanza di visualizzazione dal livello del modello o entrambi.
Ogni servizio può interagire con qualsiasi numero (sebbene di solito è solo una manciata) di oggetti di dominio e astrazioni di archiviazione. Ad esempio, RecogitionService
non potrebbe importare di meno delle astrazioni di archiviazione per gli articoli.
Note di chiusura
In questo modo si ottiene un'applicazione che può essere testata in unità a qualsiasi livello, ha un basso accoppiamento (se implementata correttamente) e ha un'architettura chiaramente comprensibile.
Tuttavia, tieni presente: MVC non è pensato per piccole applicazioni. Se stai scrivendo una pagina del guestbook utilizzando il pattern MVC, lo stai facendo in modo sbagliato. Questo modello è pensato per far rispettare la legge e l'ordine su applicazioni su larga scala.
Per le persone che utilizzano PHP come lingua principale, questo post potrebbe essere pertinente. È una descrizione un po 'più lunga del livello del modello con alcuni frammenti di codice.