Le MVC n'est-il pas anti-POO?


62

L'idée principale derrière la POO est d'unifier les données et le comportement dans une seule entité - l'objet. En programmation procédurale, il existe des données et des algorithmes distincts modifiant les données.

Dans le modèle Modèle-Vue-Contrôleur, les données et la logique / algorithmes sont placés dans des entités distinctes, le modèle et le contrôleur, respectivement. Dans une approche équivalente en POO, le modèle et le contrôleur ne doivent-ils pas être placés dans la même entité logique?


11
Pourquoi auraient-ils besoin d'être dans la même entité logique? Vous n'avez pas expliqué pourquoi cela serait avantageux ou pourquoi OOP dicterait cet arrangement.
Robert Harvey

26
Eh bien, la logique métier appartient au modèle, pas au contrôleur. Le contrôleur est vraiment juste un intermédiaire pour coller ensemble la vue et le modèle. Donc, dans le modèle, vous avez les données et le comportement au même endroit.
Robert Harvey

2
Quelle? Unifier les données et le comportement est exactement ce qu’est la POO.
Andy

3
OOP concerne la séparation des implémentations des interfaces. Les interfaces ont plus à voir avec le comportement et les implémentations plus avec les données (c'est pourquoi les données ont tendance à être cachées). Donc, la POO ne consiste pas à unifier les données et le comportement, mais à les séparer.
Kaz

5
Quoi qu'il en soit, vous ne voulez pas regrouper toutes les données et tous les comportements dans une même classe. Les programmes POO utilisent plusieurs classes pour créer des cadres d'objets. Et de toute façon, si quelque chose est "anti-OOP", cela pourrait être une bonne chose. La programmation orientée objet n'est pas la solution ultime. OOP carrément suce. Il est temps de surmonter la POO.
Kaz

Réponses:


45

MVC est un exercice de séparation des préoccupations , une architecture d'interface utilisateur. C'est un moyen de remédier à la complexité qui peut survenir dans les interfaces utilisateur du fait que la présentation n'est pas séparée du contenu .

En théorie, tous les objets peuvent avoir un comportement qui agit sur les données qu'ils contiennent, et ces données et ce comportement restent encapsulés . En pratique, un objet OOP donné peut avoir ou non une logique qui correspond à ses données, ou peut ne pas avoir de logique du tout (un objet de transfert de données , par exemple).

Dans MVC, la logique métier est intégrée au modèle et non au contrôleur. Le contrôleur est vraiment juste un intermédiaire pour coller ensemble la vue et le modèle. Ainsi, dans le modèle, vous pouvez avoir les données et le comportement au même endroit.

Mais même cet arrangement ne garantit pas une fusion stricte données / comportement. Les objets contenant uniquement des données peuvent être exploités par d'autres classes contenant uniquement de la logique, ce qui est une utilisation parfaitement acceptable de la POO.


Je vais vous donner un exemple spécifique. C'est un peu artificiel, mais supposons que vous ayez un Currencyobjet, et que cet objet ait la capacité de se représenter dans n'importe quelle devise disponible, indexée sur le dollar. Donc, vous auriez des méthodes comme:

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

... et ce comportement serait encapsulé avec l'objet Devise.

Mais que se passe-t-il si je souhaite transférer la devise d'un compte à un autre ou déposer une devise? Ce comportement serait-il également encapsulé dans l'objet Devise? Non, ce ne serait pas. L'argent dans votre portefeuille ne peut pas être transféré de votre portefeuille dans votre compte bancaire; vous avez besoin d’un ou de plusieurs agents (guichet automatique ou guichet automatique) pour vous aider à transférer cet argent sur votre compte.

Alors que le comportement serait encapsulé dans un Tellerobjet, et il accepterait Currencyet des Accountobjets comme des entrées, mais il ne contiendrait aucune donnée elle - même, sauf peut - être un peu d'état local (ou peut - être un Transactionobjet) pour aider à traiter les objets d'entrée.


Et dans quelle entité / package faut-il la Tellerplacer? À Controllerpartir de où les Teller'sméthodes sont appelées ou à Modelcause de la logique métier?
m3th0dman

Tellerva dans le Model, bien qu'il puisse être appelé par le contrôleur. Cela fait partie du domaine des affaires.
Robert Harvey

J'ai toujours pensé que l'utilisation du modèle de règles métier faisait de MVC un modèle semi-efficace. L'utilisation du modèle pour les adaptateurs dans l'application réelle et la possibilité pour les contrôleurs d'assurer la médiation entre les adaptateurs et la vue sont toujours beaucoup plus efficaces pour obtenir un système sur puce.
Yam Marcovic

@YamMarcovic: Je ne suis pas sûr de ce que vous voulez dire. Le modèle est une sorte de fourre-tout; dans la pratique, les règles métier sont généralement placées dans leur propre couche de service, mais elles sont toujours considérées comme faisant partie du modèle (par exemple, vous ne coderiez pas de règles métier spécifiques dans une méthode de contrôleur individuelle). Vous avez raison de dire que les contrôleurs sont un intermédiaire.
Robert Harvey

5
Une chose que je pense que la plupart des gens se trompent à propos de MVC simplement en lisant dessus est des hypothèses trop larges sur ce que signifie "la logique métier". Si vous ne parvenez pas à afficher votre modèle et à l'utiliser avec une modification minimale, voire aucune, dans une toute nouvelle application ayant les mêmes objectifs commerciaux mais une architecture très différente via un contrôleur avec une logique d'application totalement différente, vous ne le faites pas correctement. OMI. Il est toujours utile de dissocier des vues de tout ce que vous avez, bien sûr, mais C, en tant que construction légère, me manque comme un point de séparation essentiel.
Erik Reppen

73

MVC fonctionne à un niveau d'abstraction beaucoup plus élevé que les objets simples et, en réalité, chacun des trois (modèle, vue et contrôleur) est généralement constitué de nombreux objets contenant à la fois des données et un comportement.

Le fait que les objets qui encapsulent des données et des comportements constituent un bon élément fondamental pour les programmes en général ne signifie pas que ce soit le meilleur modèle à tous les niveaux d'abstraction et à toutes les fins.


L'approche orientée objet peut évoluer en niveau d'abstraction; voyez par exemple la raison derrière Domain Driven Design qui est apparue parce que l'architecture en couches classique n'est pas OOPish mais plutôt procédurale. Cela se produit à un niveau d'abstraction plus élevé que MVC.
m3th0dman

6
@ m3th0dman: Vous parlez en termes généraux et généraux. Pourquoi ne pas discuter de détails, comme comment MVC élimine le cauchemar des codes spaghettis qu'est Winforms ou Webforms?
Robert Harvey

3
@ m3th0dman: c'est une caractérisation assez simpliste de DDD.
Michael Borgwardt

1
@RobertHarvey Pour vous assurer que vous êtes le contrepoint de la raison pour laquelle MVC est bon parce qu'il supprime les spaghettis, il n'est pas vraiment au rendez-vous ici. Je suis d'accord mais j'ai tendance à voir MVC implémenté dans le schéma procédural. Donc, je pense que c'est une question pertinente à poser, ou plutôt - peut-être que la question à poser est "À quelle fréquence les gens mettent-ils en œuvre la procédure MVC de manière procédurale?"
Jimmy Hoffa

1
@ Robert Harvey Le but de la question n'est pas de savoir si MVC est bon ou mauvais; il s'agit du fait que repose ou non sur les principes OO.
m3th0dman

71

La POO ne limite pas les interactions entre des objets ayant chacun leurs propres données et leur propre comportement.

Pensez à une analogie de colonie de fourmis et de fourmis: le comportement d’une fourmi individuelle (courir toute la journée, apportant de la nourriture) est différent du comportement de la colonie en général (trouver l’endroit le plus souhaitable, faire plus de fourmis). Le modèle MVC décrit la structure sociale souhaitée pour une colonie de fourmis, tandis que la programmation orientée objet guide la conception des fourmis individuelles.


5
+1: Je n'aime généralement pas les explications par des analogies, mais celle-ci est brillante.
Michael Borgwardt

@Caleb C'est un excellent point, merci beaucoup!
dasblinkenlight

19

La POO concerne également la séparation des préoccupations , c'est-à-dire la séparation des différents rôles / responsabilités dans différents objets.

MVC se sépare en ces composants:

  • Modèle: la donnée et sa logique métier
  • Vue: représentation des données
  • Contrôleur: coordination entre le modèle et la vue.

Ces responsabilités sont donc clairement distinctes et doivent en effet être séparées en plusieurs entités.


Il est vrai que le principe de responsabilité unique est utile pour utiliser efficacement la POO, mais je pense qu’il est exagéré de dire que "la POO concerne également le principe de responsabilité unique". Cela semble en retard.
Caleb

@Caleb Ouais, je comprends ce que tu veux dire. Peut-être que cela pourrait être reformulé mais vous comprenez le point.
marco-fiset

18

Dans le modèle Modèle-Vue-Contrôleur, les données et la logique / algorithmes sont placés dans des entités distinctes, le modèle et le contrôleur, respectivement.

Le modèle et le contrôleur sont deux rôles distincts. Un modèle a à la fois un état et une logique, et un contrôleur a à la fois un état et une logique. Le fait qu'ils communiquent ne rompt pas l'encapsulation de l'un ou de l'autre - le contrôleur ne sait ni ne tient à la façon dont le modèle stocke ses données, ou ce qu'il fait aux données lorsque le contrôleur récupère ou met à jour une partie de celles-ci. Le modèle ne sait pas ou se soucie de ce que le contrôleur fait avec les données fournies par le modèle.

Pensez-y de cette façon: si les objets ne pouvaient pas faire passer des données sans encapsuler leur encapsulation, vous ne pouviez en réalité avoir qu'un seul objet!

Dans une approche équivalente en POO, le modèle et le contrôleur ne doivent-ils pas être placés dans la même entité logique?

MVC est une approche POO - en particulier, c'est une recette pour décider comment utiliser des objets pour organiser efficacement un programme. Et non , le modèle et le contrôleur ne doivent pas être la même entité. Un contrôleur permet de séparer le modèle et la vue. Garder le modèle et la vue indépendants l'un de l'autre les rend plus testables et plus réutilisables.


J'espère que le contrôleur a une logique mais peu ou pas d'état. Quel genre d'état pensez-vous que le contrôleur a?
Matthew Flynn

1
@ MatthewFlynn Pour commencer, un contrôleur doit connaître la vue et le modèle. Au-delà, cela peut dépendre de la version particulière de MVC dont nous parlons, mais en général, un contrôleur peut garder un état lié à la manière dont les informations doivent être affichées (par exemple, la sélection en cours), alors que le modèle traite quelles informations sont affichées.
Caleb

1
@ MattFenwick C'est ce que je veux dire par "saveur" ... C'est exactement ce que vous stockez dans le contrôleur et dans le modèle une question de goût et de convention. Dans Cocoa / Cocoa Touch, il est courant de conserver des éléments tels que la sélection actuelle et même les préférences de l'utilisateur dans le contrôleur. MVC tel qu'utilisé dans certains frameworks Web peut mettre presque tout dans le modèle et très peu dans le contrôleur. YMMV.
Caleb

4
@MatthewFlynn Most sera d'accord avec vous, mais pour la première fois, les gens considèrent que la logique commerciale est une catégorie plus large que ce qu'elle est censée être. Le contrôleur gère la logique d'application, ce qui confond souvent les utilisateurs avec la logique métier. Dans une séparation idéale des préoccupations, je devrais être en mesure de réutiliser un objet modèle dans une architecture d'application totalement différente, servant les mêmes objectifs métier sans modification de l'objet métier. Tout ce que la nouvelle application doit faire est d’utiliser l’interface et de faire sa propre chose avec les données et les transactions telles que retournées et traitées.
Erik Reppen

1
@ MattFenwick: envisager une application multi-utilisateur. Un point évident pour tracer la ligne entre le modèle et le contrôleur est que ce modèle gère l’état partagé et le contrôleur l’état local. La sélection actuelle est locale, donc elle va dans le contrôleur.
Jan Hudec

4

MVC est un modèle qui décrit un moyen raisonnable pour que les objets interagissent; ce n'est pas en soi une méta-classe. En plus de cela, OO consiste à décrire les comportements et les données d'entités, et comment ces entités interagissent. Il ne s'agit pas d'unifier l'ensemble du système en un seul objet massif.


2

Le contrôleur ne représente pas le comportement d'un modèle. Les contrôleurs représentent tous le comportement de l'application dans son ensemble _ ce qu'un utilisateur peut faire et ce qu'il peut voir.

Il est faux de considérer les contrôleurs et les modèles comme un seul. Ils ont des objectifs différents, une sémantique différente et ne doivent donc pas être unifiés dans un seul objet.


2

La couche modèle n'est pas simplement une donnée, pas plus que la couche contrôleur est simplement logique.

La couche contrôleur aura une collection complète d'objets pour ses besoins. Il y aura des objets pour recevoir une entrée de la vue et pour transformer cette entrée en une forme que le modèle peut traiter. Le framework Java Struts en est un bon exemple dans son modèle Action / Form. Le formulaire est rempli avec les entrées de l'utilisateur, puis transmis à l'action. L'action utilise ces données et les utilise pour manipuler le modèle.

De la même manière, la couche modèle ne consiste pas uniquement en données. Prenez un objet Utilisateur, par exemple. Vous aurez peut-être besoin d'un code qui extrait un utilisateur d'une base de données, ou d'un code permettant d'associer un utilisateur à une commande, ou pour valider que l'adresse de l'utilisateur se trouve dans la zone desservie par votre société ... vous obtenez le image. Ce n'est pas la logique du contrôleur. C'est la logique métier, et cela a amené beaucoup à scinder leur couche Modèle en plusieurs couches, telles que les couches Service ou Manager pour la logique métier, une couche DAO (Database Access Object) pour l'accès à la base de données, etc.

MVC n'est pas une méthode pour organiser des opérations de modèle individuelles. Cela fonctionne à un niveau supérieur, c'est une méthode pour organiser l'accès à l'application. La vue sert à présenter des données et des actions humaines pour la manipuler, le contrôleur sert à la conversion entre les actions de l'utilisateur et les différentes vues, et le modèle indique l'emplacement des données commerciales et de leurs raisons commerciales.


2

Le but de la POO est de regrouper des données et des fonctionnalités qui vont ensemble . Un calcul basé sur une donnée n’appartient pas toujours à cette donnée.

Dans MVC, la fonctionnalité permettant d'afficher une donnée (vue) est séparée des données (modèle). Pourquoi donc? C'est spécifiquement pour que la logique d'affichage puisse être changée sans avoir à changer les données sous-jacentes. Cela facilite la modification de la vue lorsque vous devez effectuer une présentation différente des mêmes données: ou lorsque les caractéristiques du matériel d'affichage changent: ou lorsque vous passez de Windows à Linux. ou lorsque vous voulez que deux personnes aient deux manières différentes d’examiner les mêmes données.

MVC n'entre pas en conflit avec la programmation orientée objet - il découle en fait d'une application correcte des principes orientés objet.


0

Je crois que vous confondez les données persistantes liées à un objet de modèle avec les données d'application des bases de données avec lesquelles le modèle interagit. Un modèle contient une logique métier et des règles permettant de travailler avec des bases de données et d'effectuer des transactions. Il peut définir et vérifier des indicateurs d'état internes, par exemple s'il existe une vente aujourd'hui, si l'utilisateur est éligible pour le statut VIP, puis branchez la logique en conséquence lorsque vient le temps d'accéder, de définir, de manipuler des données ou de procéder à un achat. Ce sont ces indicateurs dont nous parlons lorsque nous discutons d'objets en termes d'encapsulation d'un ensemble de méthodes et de valeurs ou de données persistantes.

Tout comme l’objet modèle conserve les données permettant d’établir quelles règles commerciales sont en jeu, un contrôleur doit, OMI, conserver des données plus générales sur l’état de l’application, pertinentes pour déterminer le comportement de l’application, par exemple si l’utilisateur est connecté ou dispose d’un crédit valide. données de carte en place. Les méthodes de modèle détermineraient en premier lieu l'état de ces éléments, mais il est logique que le contrôleur conserve des indicateurs pertinents pour le flux général des applications s'ils ne s'appliquent pas à la manière dont l'entreprise est exécutée ou aux transactions de données exécutées. Une fois que vous avez déterminé qu'ils ne sont pas connectés, ne dérangez même pas le modèle avec des vérifications d'état des utilisateurs jusqu'à ce qu'une nouvelle tentative de connexion soit effectuée.

De même, avec un objet de vue approprié, par opposition aux modèles HTML plus typiques que vous voyez dans la plupart des infrastructures Web côté serveur. Une fois que les préférences de couleur de l'utilisateur sont chargées, il convient que la vue conserve ces données et les exécute. Le chargement, la validation et la modification des paramètres sont tous des problèmes de modèle, mais ils ne devraient l'être qu'une fois, jusqu'à ce que des modifications soient apportées.

OMI, rien ne dit que les contrôleurs ne peuvent pas être des objets composites avec des vues et des modèles en tant qu'objets globaux internes. Cela a du sens si vous appliquez MVC à une échelle plus petite, comme une fabrique de widgets d'interface utilisateur, car le contrôleur est l'endroit idéal pour exposer une interface à des objets d'application de niveau supérieur tout en enfouissant les données et les détails logiques de l'interaction entre View et Model. Cela n'a pas vraiment de sens pour les objets d'application monolothiques où le contrôleur est vraiment l'objet de plus haut niveau.


0

Si je comprends bien; L'argument est architecture par composant vs POO. Et sans entrer dans la guerre de religion, je pense qu'ils décrivent tous les deux la même chose; il suffit de regarder sous différents angles.

Par exemple, l'objectif principal de OOP / OOD est de rendre votre code plus modulaire et réutilisable. Oui?

Quel est exactement l'objectif de l'architecture à base de composants. Donc, ils sont plus semblables que toute autre chose.

Je pense que MVC n’est que l’évolution naturelle de la POO et j’ose le dire; un meilleur moyen d'organiser vos objets, de séparer les problèmes et de réutiliser le code.


Je dirais que MVC et Component-Based Architecture sont des modèles de conception qui ne sont pas en dehors du domaine des approches POO, tandis que OOD / OOP est tout simplement un tas de confusion et de heurts entre des écoles de pensée et des malacademia sur la manière d'utiliser une programmation omniprésente frontalière. construire correctement. Comparer les deux catégories de choses revient à comparer des carrés et le stylo que vous utilisiez pour les dessiner.
Erik Reppen

-1

Je suis en retard à cette soirée et, considérant toutes les réponses avant la mienne, j'avoue que je n'ai pas grand-chose à offrir. Mais il me semble que la question ne concerne pas le modèle lui-même mais la mise en œuvre. MVC en soi ne se prête pas à une méthodologie particulière. En fait, je peux facilement imaginer un code orienté procédure dans un modèle MVC (ce que je pensais que vous sous-entendiez).

Donc, je pense que la vraie question est: Sommes-nous plus enclins au code procédural lorsque nous utilisons le modèle MVC?

(et peut-être que je vais juste avoir quelques votes?)


-1

Pas anti, mais OOP n'est pas nécessaire pour MVC.

Parce que les contrôleurs, qui sont généralement représentés par classess ne contiennent aucune donnée. Pour lesquelles des fonctions pures suffiraient.

Si vous allez plus loin et séparez les données du comportement, par exemple, supposons que les modèles ne fonctionnent que sur des données de base de données, qu'ils extraient à chaque fois que leur fonction (chargée de la manipulation des données) est appelée (au lieu de stocker un type de données dans l'instance). champs) - alors vous pouvez dire la même chose pour les modèles.

Pour aller plus loin, si vous prenez la couche d'affichage d'une application et la divisez de la même manière, vous conclurez que MVC n'a rien à voir avec la POO et qu'il est tout à fait possible d'écrire une implémentation de MVC sans aucune douleur en utilisant uniquement une approche procédurale. .


Haha, je vois que certaines personnes ont mal au a ** face aux faits. Trop d’efforts pour créer ses propres cadres avec OOP? Ne peut pas supporter le temps perdu? Les réponses les plus simples sont les meilleures.
luke1985

Vous ne savez pas pourquoi cette réponse a des votes négatifs. Il dit qu'ils ne sont pas liés, et non "anti". Semble assez précis.
mwilcox

-3

À mon avis, les OOP présentent un inconvénient car, étant donné que les données et le comportement sont moulés comme une entité (classe), ils présentent plus d’effet de couplage que de cohésion. Par ailleurs, MVC a un modèle contenant ... (Beans, DAOs, autres classes logiques), un contrôleur qui spécifie comment le contrôle doit se déplacer et des vues pour déterminer comment les données doivent être affichées sont indiquées séparément. Sur cette base, peu importe si le projet est trop gros pour être préparé, il peut être facilement créé en tant qu'entité distincte autre que de se mélanger contrairement à la POO. Le problème est résolu de manière logique, tout comme la stratégie diviser n conquérir et MVC le suit au mieux.


Est-ce seulement votre opinion ou vous pouvez le sauvegarder d'une manière ou d'une autre?
moucherai
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.