MVC non è anti OOP?


62

L'idea principale dietro OOP è quella di unificare i dati e il comportamento in una singola entità: l'oggetto. Nella programmazione procedurale ci sono dati e algoritmi separati che modificano i dati.

Nel modello Model-View-Controller i dati e la logica / algoritmi sono collocati in entità distinte, rispettivamente il modello e il controller. In un approccio OOP equivalente, il modello e il controller non dovrebbero essere collocati nella stessa entità logica?


11
Perché dovrebbero essere nella stessa entità logica? Non hai dichiarato perché ciò sarebbe vantaggioso o perché OOP avrebbe dettato questo accordo.
Robert Harvey,

26
Bene, la logica aziendale va nel modello, non nel controller. Il controller è davvero solo una via di mezzo per incollare insieme la vista e il modello. Quindi, nel modello, hai dati e comportamento nello stesso posto.
Robert Harvey,

2
Che cosa? Unificare i dati e il comportamento insieme è esattamente ciò di cui si occupa OOP.
Andy,

3
OOP riguarda la separazione delle implementazioni dalle interfacce. Le interfacce hanno più a che fare con il comportamento e le implementazioni più con i dati (motivo per cui i dati tendono a essere nascosti). Quindi OOP non riguarda l'unificazione di dati e comportamenti ma la loro separazione.
Kaz,

5
Ad ogni modo, non vuoi raggruppare tutti i dati e i comportamenti in una classe. I programmi OOP utilizzano più di una classe per creare framework di oggetti. E comunque, se qualcosa è "anti-OOP", potrebbe essere una buona cosa. OOP non è il fine di tutto. OOP fa schifo. È tempo di superare OOP.
Kaz,

Risposte:


45

MVC è un esercizio di Separation of Concerns , un'architettura UI. È un modo per correggere la complessità che può verificarsi nelle interfacce utente a causa della presentazione non separata dal contenuto .

In teoria, tutti gli oggetti possono avere un comportamento che opera sui dati in essi contenuti e che dati e comportamento rimangono incapsulati . In pratica, un determinato oggetto OOP può o meno avere una logica che corrisponde ai suoi dati o potrebbe non avere alcuna logica ( ad esempio un oggetto di trasferimento dati ).

In MVC, la logica aziendale va nel modello, non nel controller. Il controller è davvero solo una via di mezzo per incollare insieme la vista e il modello. Quindi, nel modello, puoi avere dati e comportamento nello stesso posto.

Ma anche tale accordo non garantisce una fusione rigorosa di dati / comportamenti. Gli oggetti che contengono solo dati possono essere gestiti da altre classi contenenti solo la logica, e questo è un uso perfettamente accettabile di OOP.


Ti faccio un esempio specifico. Questo è un po 'inventato, ma supponiamo che tu abbia un Currencyoggetto, e quell'oggetto ha la capacità di rappresentarsi in qualsiasi valuta disponibile, ancorata al dollaro. Quindi avresti metodi come:

public decimal Yen { get { return // dollars to yen; } }
public decimal Sterling { get { return // dollars to sterling; } }
public decimal Euro { get { return // dollars to euro; } }

... e quel comportamento sarebbe incapsulato con l'oggetto Valuta.

E se volessi trasferire la valuta da un conto a un altro o depositare una valuta? Tale comportamento verrebbe anche incapsulato nell'oggetto Valuta? No, non lo farebbe. Il denaro nel tuo portafoglio non può trasferirsi dal tuo portafoglio al tuo conto bancario; hai bisogno di uno o più agenti (un cassiere o un bancomat) per aiutarti a ottenere quei soldi sul tuo conto.

Quindi quel comportamento sarebbe incapsulato in un Telleroggetto, e accetterebbe Currencye Accountoggetti come input, ma non conterrebbe alcun dato stesso, tranne forse un po 'di stato locale (o forse un Transactionoggetto) per aiutare a elaborare gli oggetti di input.


E in quale entità / pacchetto dovrebbe Telleressere collocato? Nella Controllerda dove i Teller'smetodi vengono chiamati o in Modelparte, perché è la logica di business?
m3th0dman,

Tellerva in Model, anche se potrebbe essere chiamato dal controller. Fa parte del dominio aziendale.
Robert Harvey,

Ho sempre pensato che l'uso del modello per le regole aziendali rendesse MVC un modello semi-efficace. L'utilizzo del Modello per adattatori per l'applicazione reale e il fatto che i controller mediano tra gli adattatori e la vista è sempre molto più efficace nel raggiungimento del SoC.
Yam Marcovic,

@YamMarcovic: non sono sicuro di cosa intendi. Il modello è una specie di catch-all; in pratica, le regole aziendali vengono generalmente collocate nel proprio livello di servizio, ma è comunque considerata parte del Modello (ad esempio, non si codificheranno regole aziendali specifiche all'interno di un singolo metodo del controller). Hai ragione sul fatto che i controller sono un intermediario.
Robert Harvey,

5
Una cosa che penso che la maggior parte delle persone stia sbagliando su MVC solo leggendo su di essa sono ipotesi troppo ampie su cosa significhi "logica aziendale". Se non riesci a far apparire il tuo modello e utilizzarlo con modifiche minime o nulle in un'app nuovissima che avrà gli stessi obiettivi aziendali ma un'architettura molto diversa tramite un controller con una logica applicativa completamente diversa, stai sbagliando IMO. C'è ancora valore nel disaccoppiare le viste da qualsiasi combinazione di tutto il resto, ovviamente ma C come costrutto leggero mi sembra mancare un punto chiave di separazione.
Erik Reppen,

73

MVC funziona a un livello di astrazione molto più elevato rispetto ai singoli oggetti, e in effetti ciascuno dei tre (modello, vista e controller) sarà in genere costituito da molti oggetti che hanno ciascuno dati e comportamento.

Che gli oggetti che incapsulano dati e comportamento siano un buon elemento fondamentale per i programmi in generale non significa che sia il miglior modello a tutti i livelli di astrazione e per tutti gli scopi.


L'approccio orientato agli oggetti può ridimensionarsi a livello di astrazione; vedi per esempio il motivo dietro Domain Driven Design che è apparso perché la classica architettura a strati non è OOPish ma piuttosto procedurale. Ciò accade a un livello di astrazione più elevato rispetto a MVC.
m3th0dman,

6
@ m3th0dman: stai parlando in generale, ampie generalità. Che ne dici di discutere di dettagli, come il modo in cui MVC elimina l'incubo di spaghetti-code che è Winforms o Webforms?
Robert Harvey,

3
@ m3th0dman: questa è una caratterizzazione piuttosto semplicistica di DDD.
Michael Borgwardt,

1
@RobertHarvey Per essere sicuro di essere il contrappunto del perché MVC è buono perché elimina gli spaghetti non è davvero in discussione qui. Sono d'accordo, ma tendo a vedere MVC implementato anche nel modello procedurale. Quindi penso che sia una domanda rilevante da porre, o piuttosto- forse la domanda da porsi è "Quanto spesso le persone implementano MVC in modo procedurale?"
Jimmy Hoffa,

1
@Robert Harvey Lo scopo della domanda non è di quanto MVC sia buono o cattivo; si tratta del fatto che si basa o meno sui principi OO.
m3th0dman,

71

OOP non limita le interazioni tra oggetti che hanno ciascuno i propri dati e il proprio comportamento.

Pensa a una formica e a un'analogia della colonia di formiche: il comportamento di una singola formica (corri tutto il giorno, portando cibo) è diverso dal comportamento della colonia generale (trova il posto più desiderabile, crea più formiche). Il modello MVC descrive la struttura sociale desiderata di una colonia di formiche, mentre OOP guida la progettazione di singole formiche.


5
+1: di solito non mi piacciono le spiegazioni attraverso le analogie, ma questa è geniale.
Michael Borgwardt,

@Caleb Questo è un punto eccellente, grazie mille!
dasblinkenlight,

19

OOP riguarda anche la separazione delle preoccupazioni , ovvero la separazione di ruoli / responsabilità diversi in oggetti diversi.

MVC si separa in questi componenti:

  • Modello: i dati e la sua logica aziendale
  • Visualizza: rappresentazione dei dati
  • Controller: coordinamento tra il modello e la vista.

Quindi queste responsabilità sono chiaramente distinte e dovrebbero effettivamente essere separate in più entità.


È vero che il principio della singola responsabilità è utile nell'uso efficace della OOP, ma penso che sia un tratto affermare che "OOP riguarda anche il principio della responsabilità singola". Sembra arretrato.
Caleb,

@Caleb Sì, capisco cosa intendi. Forse potrebbe essere riformulato ma hai capito.
marco-fiset,

18

Nel modello Model-View-Controller i dati e la logica / algoritmi sono collocati in entità distinte, rispettivamente il modello e il controller.

Modello e controller sono due ruoli distinti. Un modello ha sia stato che logica e un controller ha sia stato che logica. Il fatto che comunichino non interrompe l'incapsulamento di nessuno dei due: il controller non sa né si preoccupa di come il modello memorizza i suoi dati o di cosa fa ai dati quando il controller ne recupera o aggiorna una parte. Il modello non sa né si preoccupa di ciò che fa il controller con i dati forniti dal modello.

Pensala in questo modo: se gli oggetti non potessero passare avanti e indietro i dati senza interrompere l'incapsulamento, potresti davvero avere un solo oggetto!

In un approccio OOP equivalente, il modello e il controller non dovrebbero essere collocati nella stessa entità logica?

MVC è un approccio OOP - in particolare, è una ricetta per decidere come utilizzare gli oggetti per organizzare un programma in modo efficace. E no , il modello e il controller non dovrebbero essere la stessa entità. Un controller consente la separazione tra modello e vista. Mantenere il modello e la vista indipendenti l'uno dall'altro li rende entrambi più testabili e più riutilizzabili.


Spero che il controller abbia una logica ma poco o nessun stato. Che tipo di stato stai pensando abbia il controller?
Matthew Flynn,

1
@MatthewFlynn Per cominciare, un controller deve conoscere la vista e il modello. Oltre a ciò, potrebbe dipendere da quale particolare sapore di MVC stiamo parlando, ma in generale un controller potrebbe mantenere lo stato correlato a come devono essere visualizzate le informazioni (ad esempio la selezione corrente), mentre il modello si occupa di quali informazioni vengono visualizzate.
Caleb,

1
@MattFenwick Questo è ciò che intendo per il "sapore" ... Esattamente ciò che memorizzi nel controller e ciò che nel modello è una questione di gusti e convenzioni. In Cocoa / Cocoa Touch, è comune mantenere nel controller cose come la selezione corrente e persino le preferenze dell'utente. MVC come usato in alcuni framework web può mettere quasi tutto nel modello e pochissimo nel controller. YMMV.
Caleb,

4
@MatthewFlynn La maggior parte sarà d'accordo con te, ma IMO, le persone considerano la logica aziendale più ampia di quanto si supponga. Il controller gestisce la logica dell'applicazione che le persone spesso vengono confuse con la logica aziendale. In una separazione ideale delle preoccupazioni, dovrei essere in grado di riutilizzare un oggetto modello in un'architettura di app completamente diversa che serve gli stessi obiettivi di business senza modifiche all'oggetto di business. Tutto ciò che la nuova applicazione deve fare è usare l'interfaccia e fare le proprie cose con i dati e le transazioni come restituiti ed elaborati.
Erik Reppen,

1
@MattFenwick: considera l'applicazione multiutente. Un punto ovvio per tracciare la linea tra modello e controller è che il modello gestisce lo stato condiviso e il controller lo stato locale. La selezione corrente è locale, quindi va nel controller.
Jan Hudec,

4

MVC è un modello che descrive un modo ragionevole per gli oggetti di interagire; non è esso stesso una meta-classe. A questo proposito, OO riguarda la descrizione dei comportamenti e dei dati delle entità e il modo in cui tali entità interagiscono. Non si tratta di unificare l'intero sistema in un unico oggetto enorme.


2

Il controller non rappresenta il comportamento di un modello. I controller rappresentano il comportamento dell'intera applicazione _ cosa può fare un utente e cosa può vedere un utente.

È errato visualizzare controller e modelli come uno. Hanno scopi diversi, semantica diversa e quindi non dovrebbero essere unificati in un oggetto.


2

Il livello del modello non è semplicemente un dato non più di quanto il livello del controller sia semplicemente logico.

Il livello controller avrà una raccolta completa di oggetti per i suoi scopi. Ci saranno oggetti per ricevere input dalla vista e per trasformare quell'input in una forma che il modello può elaborare. Il framework Struts Java ne ha un buon esempio nel suo modello Action / Form. Il modulo viene popolato con l'input dell'utente e quindi passato all'azione. L'Azione prende quei dati e li usa per manipolare il modello.

Allo stesso modo, il livello Modello non è costituito interamente da dati. Prendi un oggetto Utente, ad esempio: potresti aver bisogno di un codice che ottiene un utente da un database o un codice per associare un Utente a un Ordine o per convalidare che l'indirizzo dell'Utente si trova nell'area dei servizi della tua azienda ... ottieni il immagine. Questa non è la logica del controller. È la logica aziendale e ha portato molti a dividere il proprio livello Modello in diversi livelli come i livelli Service o Manager per la logica aziendale, un livello DAO (Database Access Object) per l'accesso al database e altri.

MVC non è un metodo per organizzare le singole operazioni del Modello. Funziona a un livello superiore a quello - è un metodo per organizzare il modo in cui si accede all'applicazione. View serve per presentare dati e azioni umane per manipolarli, Controller serve per la traduzione tra le azioni degli utenti e le varie visualizzazioni e il Modello è il luogo in cui risiedono i dati aziendali e le ragioni commerciali per cui esistono.


2

Il punto di OOP è di raggruppare dati e funzionalità che appartengono insieme . Un calcolo basato su alcuni dati non sempre appartiene a tali dati.

In MVC la funzionalità per visualizzare un dato (vista) è mantenuta separata dai dati (modello). Perché? In particolare, è possibile modificare la logica di visualizzazione senza dover modificare i dati sottostanti. Rende facile cambiare la vista ogni volta che è necessario creare una presentazione diversa degli stessi dati: o quando cambiano le caratteristiche dell'hardware del display: o quando si passa da Windows a Linux; o quando vuoi che due persone abbiano due modi diversi di guardare gli stessi dati.

MVC non è in conflitto con OOP - in realtà è derivato da una corretta applicazione dei principi orientati agli oggetti.


0

Credo che tu stia confondendo i dati persistenti associati a un oggetto modello con i dati dell'applicazione dei database con cui interagisce il modello. Un modello contiene regole di business e regole per lavorare con database e condurre transazioni. Potrebbe impostare e controllare flag di stato interni, ad esempio se oggi esiste una vendita, se l'utente si qualifica per lo stato VIP e quindi la logica della filiale di conseguenza quando arriva il momento di accedere, impostare o manipolare i dati o condurre un acquisto. Sono quelle bandiere di cui stiamo parlando quando discutiamo di oggetti in termini di incapsulamento di un insieme di metodi e valori o dati persistenti.

Proprio come l'oggetto modello conserva i dati per stabilire quali regole aziendali sono in gioco, un controller dovrebbe, IMO, conservare dati sullo stato dell'applicazione più pertinenti pertinenti al comportamento dell'app, ad esempio se l'utente ha effettuato l'accesso o ha un credito valido dati della carta in atto. I metodi modello determinerebbero in primo luogo lo stato di queste cose, ma ha senso che il controller mantenga i flag pertinenti al flusso generale delle app se non si applicano al modo in cui l'attività viene gestita o alle transazioni di dati. Dopo aver stabilito che non hanno effettuato l'accesso, non disturbare il modello con i controlli dello stato utente fino a quando non è stato eseguito un altro tentativo di accesso.

Allo stesso modo con un oggetto di visualizzazione appropriato rispetto ai modelli HTML più tipici che vedi nella maggior parte dei framework Web sul lato server. Una volta caricate le preferenze di colore dell'utente, dovrebbe essere la vista che si attacca a quei dati e li esegue. Il caricamento, la convalida e la modifica delle impostazioni sono tutti problemi del modello, ma dovrebbero essere problemi del modello una sola volta finché non si verificano cambiamenti.

IMO, nulla dice che i controller non possano essere oggetti compositi con viste e modelli come oggetti aggregati interni. Questo ha effettivamente senso se applichi MVC su una scala più piccola come una fabbrica di widget UI poiché il controller è il luogo ideale per esporre un'interfaccia a oggetti di app di livello superiore seppellendo i dati e i dettagli logici dell'interazione tra Vista e Modello. Non ha davvero senso per gli oggetti monolotici delle app in cui il controller è davvero l'oggetto di livello più alto.


0

A quanto ho capito; L'argomento è l'architettura basata su componenti vs OOP. E senza entrare nella guerra religiosa, penso che entrambi descrivano la stessa cosa; guardandolo da diverse angolazioni.

Ad esempio, il punto centrale di OOP / OOD è rendere il codice più modulare e riutilizzabile. Sì?

Qual è esattamente l'obiettivo dell'architettura basata su componenti. Quindi sono più simili di ogni altra cosa.

Penso che MVC sia solo la naturale evoluzione di OOP e oso dirlo; un modo migliore per organizzare i tuoi oggetti, la separazione delle preoccupazioni e il riutilizzo del codice.


Direi che MVC e Component-Based Architecture sono modelli di progettazione non al di fuori del regno degli approcci OOP mentre OOD / OOP è semplicemente un mucchio di confusione e scontro di scuole di pensiero e malacademia su come usare una programmazione onnipresente al confine costruire correttamente. Confrontare le due categorie di cose è come confrontare i quadrati e la penna che hai usato per disegnare i quadrati.
Erik Reppen,

-1

Sono in ritardo a questa festa e, considerando tutte le risposte prima delle mie, ammetto di non avere molto nuovo da offrire. Ma mi sembra che la domanda non riguardi il modello stesso ma l'implementazione. MVC in sé e per sé non si presta a nessuna metodologia particolare. In effetti, posso facilmente immaginare il codice orientato alla procedura in un modello MVC (che è quello che ho sentito come se stessi implicando).

Quindi, penso che la vera domanda sia; siamo più inclini al codice procedurale quando si utilizza il modello MVC.

(e forse avrò solo qualche voto negativo?)


-1

Non anti, ma anche OOP non è richiesto per MVC.

Perché i controller, che di solito sono rappresentati da classess, non contengono dati. Per cui sarebbero sufficienti le funzioni pure.

Se si va oltre e si separano i dati dal comportamento, ad esempio supponiamo che i modelli funzionino solo sui dati del database, che recuperano ogni volta che viene chiamata la loro funzione (che è responsabile della manipolazione dei dati) (invece di archiviare alcuni tipi di dati nell'istanza campi) - quindi puoi dire lo stesso per i modelli.

Andando oltre, se prendi il livello di visualizzazione di un'applicazione e lo dividi in modo simile, finirai effettivamente con la conclusione che MVC non ha nulla a che fare con OOP, ed è completamente possibile scrivere l'implementazione MVC senza alcun dolore usando solo l'approccio procedurale .


Haha, vedo che alcune persone hanno sofferto nell'a ** di fronte ai fatti. Troppi sforzi per realizzare i propri framework con OOP? Non sopporti il ​​tempo perso? Le risposte più semplici sono le migliori.
luke1985,

Non sono sicuro del perché questa risposta abbia dei voti negativi. Sta dicendo che non sono collegati, e non "anti". Sembra abbastanza preciso.
mwilcox,

-3

A mio avviso, gli OOP presentano uno svantaggio che, poiché i (dati e comportamento) sono modellati come un'entità (Classe), ciò mostra un maggiore effetto di accoppiamento rispetto alla coesione. Mentre d'altra parte MVC ha un modello contenente ... (bean, DAO, altre classi logiche), controller che specifica come deve viaggiare il controllo e le viste per determinare come devono essere mostrati i dati in modo separato. Sulla base di questo, non importa se il progetto è troppo grande da preparare può essere facilmente realizzato come entità separata oltre a essere mescolato a differenza degli OOP. Il problema è risolto secondo un modello logico proprio come la strategia di divisione e conquista e MVC segue al massimo questo.


questa è solo la tua opinione o puoi sostenerla in qualche modo?
moscerino del
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.