I modelli grassi e i controller magri sembrano creare modelli di Dio [chiuso]


91

Ho letto molti blog che sostengono l' approccio dei modelli grassi e dei controller magri , specialmente. il campo Rails. Di conseguenza, i router stanno fondamentalmente solo cercando di capire quale metodo chiamare su quale controller e tutto ciò che il metodo del controller fa è chiamare il metodo corrispondente sul modello e quindi visualizzare la vista. Quindi ho due preoccupazioni qui che non capisco:

  1. Il controller e il router in realtà non stanno svolgendo compiti molto diversi oltre a chiamare un metodo sul modello simile a Dio basato sul percorso.
  2. I modelli stanno facendo troppo. Invio di e-mail, creazione di relazioni, eliminazione e modifica di altri modelli, attività in coda, ecc. Fondamentalmente ora hai oggetti simili a Dio che dovrebbero fare tutto ciò che può o non può riguardare la modellazione e il trattamento dei dati.

Dove traccia la linea? Non sta solo cadendo nel modello di Dio?

Risposte:


136

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 MailServiceo 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, RecogitionServicenon 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.


Risposta molto utile e completa! Conosci qualche libro che spieghi un po 'di più lo schema architettonico MVC? Soprattutto nella parte dei modelli che tutti pensano erroneamente "Il modello rappresenta i dati e non fa nient'altro". e questo suona più come l'idea di un oggetto di dominio, non il "Modello" -> tomdalling.com/blog/software-design/…
thermz

1
@thermz, per quanto ne so , non ci sono davvero i libri che si occupano esclusivamente di pattern MVC. Di solito dico alle persone di leggere PoEAA e poi di andare a scavare. Forse questo elenco di link potrebbe essere utile. Trovo che, quando le persone hanno una solida conoscenza dei principi e dei concetti OOP, il modello diventa abbastanza facile da capire.
tereško

@ tereško bella risposta. Hibernate raggiunge questo obiettivo? Non sono convinto dalle risposte qui -> stackoverflow.com/questions/1308096/...
Ankan-Zerob

@ Ankan-Zerob come potresti notare, non sono uno sviluppatore java, ma da quello che so su Hibernate, fornisce un set completo di strumenti per il livello di persistenza. Ti fornirà parte di ciò che è descritto lì, ma non un livello di modello completo.
tereško

3
@johnny non per quanto ne so. La maggior parte dei cosiddetti "framework mvc" di php sono variazioni di Rails. E, come parte del corso, la maggior parte di essi viene fornita con alcune soluzioni ORM basate su record attivi (queste cose sono notoriamente fragili ai cambiamenti di DB). È possibile implementare qualcosa di simile con SF2.x o ZF2.x, ma il punto di un quadro non è quello di implementare / esecuzione di una specifica architettura ma per fornire strumenti. Inoltre, quando si tratta di MVC, è implementato dal codice dell'applicazione e non dal framework.
tereško

5

Se le classi "modello" sono implementate male sì, la tua preoccupazione è rilevante. Una classe modello non dovrebbe fare e-mail (attività di infrastruttura).

La vera domanda è cosa implica il modello in MVC. Non è limitato alle classi POCO con pochi metodi. Modello in MVC significa dati e logica aziendale. Trattalo come un superset dei classici modelli POCO di base.

Visualizza ==== Controller ==== Model ---> Business Process layer -> Core models

Aggiungi assembly di infrastruttura e livelli di accesso ai dati e usa l'iniezione per trasferirli nel BPL, quindi il tuo processo utilizza MVC come previsto.

BPL può invocare modelli UoW / Respository ed eseguire regole di business e chiamare funzionalità di infrastruttura tramite oggetti iniettati o schemi di interfaccia.

Quindi la raccomandazione di mantenere un controller magro non significa che la classe "persona" in un modello Core classico dovrebbe avere 50 metodi e chiamare direttamente Email. Hai ragione a pensare che sia sbagliato.

Al controllore potrebbe essere comunque richiesto di istanziare e iniettare classi di infrastruttura nel BPL o nel livello principale se chiamato direttamente. Ci dovrebbe essere un livello aziendale o almeno classi che orchestrano le chiamate tra le classi del modello di oggetti classici. Beh, questo è comunque il mio "punto di vista" ;-)

Per una versione generica di MVC, la descrizione wiki http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Un piccolo blog che parla della "M" in MVC. http://www.thedeveloperday.com/skinny-controllers/


1
Se non sei d'accordo sii almeno abbastanza cortese da giustificare la tua opinione
phil soady

-1

Penso che si possa fare una distinzione tra un singolo modello fat (possibilmente denominato App o Applicazione) e diversi modelli fat suddivisi in gruppi logici (Business, Customer, Order, Message). Quest'ultimo è il modo in cui strutturo le mie app e ogni modello corrisponde approssimativamente a una tabella di database in un database relazionale o una raccolta in un database di documenti. Questi modelli gestiscono tutti gli aspetti della creazione, dell'aggiornamento e della manipolazione dei dati che compongono il modello, sia che stia parlando al database o chiamando un'API. Il controller è molto responsabile di poco più che chiamare il modello appropriato e selezionare un modello.

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.