L'idée principale derrière OOP est d'unifier les données et le comportement dans une seule entité - l'objet. Dans la programmation procédurale, il y a des données et des algorithmes séparés modifiant les données.
Dans le modèle Model-View-Controller, 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 OOP équivalente, le modèle et le contrôleur ne devraient-ils pas être placés dans la même entité logique?
MVC est un exercice dans Séparation des préoccupations , une architecture d'interface utilisateur. C'est un moyen de correler la complexité qui peut se produire dans les interfaces utilisateur en raison de la présentation n'est pas séparée du conten.
En théorie, tous les objets peuvent avoir un comportement qui opère sur les données qu'ils contiennent, et ces données et comportements restent encapsulés . En pratique, un objet OOP donné peut ou non avoir une logique correspondant à ses données, ou ne pas avoir de logique du tout (a Data Transfer Object , for exemple).
Dans MVC, la logique métier va dans le modèle, pas le 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 des données et un comportement au même endroit.
Mais même cet arrangement ne garantit pas une fusion stricte des données/comportements. Les objets contenant uniquement des données peuvent être exploités par d'autres classes ne contenant que de la logique, ce qui est une utilisation parfaitement acceptable de la POO.
Je vais vous donner un exemple précis. C'est un peu artificiel, mais disons que vous avez un objet Currency
, et cet objet a la capacité de se représenter dans n'importe quelle devise disponible, indexée sur le dollar. Vous auriez donc 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 Currency.
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 Currency? Non, ce ne serait pas le cas. L'argent dans votre portefeuille ne peut pas être transféré de votre portefeuille vers votre compte bancaire; vous avez besoin d'un ou plusieurs agents (un caissier ou un GAB) pour vous aider à mettre cet argent sur votre compte.
Ainsi, ce comportement serait encapsulé dans un objet Teller
, et il accepterait les objets Currency
et Account
comme entrées, mais il ne contiendrait aucune donnée elle-même, sauf peut-être un peu d'état local (ou peut-être un objet Transaction
) pour aider à traiter les objets d'entrée.
MVC fonctionne à un niveau d'abstraction beaucoup supérieur à celui des objets simples, et en fait chacun des trois (modèle, vue et contrôleur) sera généralement composé de nombreux objets qui ont chacun à la fois des données et un comportement.
Le fait que les objets qui encapsulent les données et le comportement soient un bon élément de base pour les programmes en général ne signifie pas que c'est le meilleur modèle à tous les niveaux d'abstraction et à toutes fins.
La POO ne restreint pas les interactions entre les objets qui ont chacun leurs propres données et leur propre comportement.
Pensez à une analogie avec une fourmi et une colonie de fourmis: le comportement d'une fourmi individuelle (courir toute la journée, apporter de la nourriture) est différent du comportement de l'ensemble de la colonie (trouver l'endroit le plus souhaitable, faire plus de fourmis). Le modèle MVC décrit la structure sociale souhaitée d'une colonie de fourmis, tandis que OOP guide la conception des fourmis individuelles.
La POO concerne également Séparation des préoccupations , c'est-à-dire séparer différents rôles/responsabilités dans différents objets.
MVC se sépare en ces composants:
Ces responsabilités sont donc clairement distinctes et doivent en effet être séparées en plusieurs entités.
Dans le modèle Model-View-Controller, les données et la logique/les 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 l'autre - le contrôleur ne sait pas ou ne se soucie pas comment 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 ne se soucie pas de ce que le contrôleur fait avec les données qu'il fournit.
Pensez-y de cette façon: si les objets ne pouvaient pas transmettre des données dans les deux sens sans interrompre l'encapsulation, vous ne pouviez vraiment avoir qu'un seul objet!
Dans une approche OOP équivalente, le modèle et le contrôleur ne devraient-ils pas être placés dans la même entité logique?
MVC est une approche OOP - en particulier, c'est une recette pour décider comment utiliser les objets pour organiser efficacement un programme . Et non, le modèle et le contrôleur ne devraient pas être la même entité. Un contrôleur permet la séparation entre le modèle et la vue. Garder le modèle et la vue indépendants l'un de l'autre les rend à la fois plus testables et plus réutilisables.
MVC est un modèle qui décrit une manière sensible pour les objets d'interagir; ce n'est pas en soi une méta-classe. À cela, OO consiste à décrire les comportements et les données des 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.
Le contrôleur ne représente pas le comportement d'un modèle. Les contrôleurs représentent ensemble le comportement de toute l'application _ ce qu'un utilisateur peut faire et ce qu'un utilisateur 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 en un seul objet.
La couche modèle n'est pas plus que des données, tout comme la couche contrôleur n'est que logique.
La couche contrôleur aura une collection complète d'objets à ses fins. Il y aura des objets pour recevoir des entrées de la vue et pour transformer ces entrées en une forme que le modèle peut traiter. Le cadre Struts Java a un bon exemple de cela dans son modèle Action/Form. Le formulaire est rempli avec des entrées de l'utilisateur, puis transmis à l'action. L'action prend ces données et utilise pour manipuler le modèle.
De la même manière, la couche Modèle n'est pas entièrement constituée de données. Prenez un objet Utilisateur, par exemple - vous pouvez avoir besoin d'un code qui obtient un utilisateur d'une base de données, ou d'un code pour associer un utilisateur à une commande, ou pour valider que l'adresse de l'utilisateur se trouve dans la zone desservie par votre entreprise ... vous obtenez le image. Ce n'est pas une logique de contrôleur. C'est la logique métier, et cela a conduit de nombreuses personnes à diviser 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 plus élevé que cela - c'est une méthode pour organiser la façon dont l'application est accessible. La vue sert à présenter les données et les actions humaines pour les manipuler, le contrôleur sert à la traduction entre les actions des utilisateurs et les différentes vues, et le modèle est l'endroit où résident les données et les raisons commerciales de leur existence.
Le point de OOP est de regrouper les données et les fonctionnalités qui appartiennent ensemble. Un calcul basé sur une certaine donnée ne fait pas appartiennent toujours à ces données.
Dans MVC, la fonctionnalité d'affichage d'une donnée (vue) est séparée des données (modèle). Pourquoi donc? C'est précisément pour que la logique d'affichage puisse être modifiée sans avoir à modifier les données sous-jacentes. Il facilite la modification de la vue chaque fois que vous devez faire 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 de regarder les mêmes données.
MVC n'est pas en conflit avec OOP - il est en fait dérivé d'une application correcte des principes orientés objet.
Si je comprends bien; L'argument est l'architecture basée sur les composants vs OOP. Et sans entrer dans la guerre de religion, je pense qu'ils décrivent tous les deux la même chose; juste le regarder sous différents angles.
Par exemple, tout l'intérêt d'OOP/OOD est de rendre votre code plus modulaire et réutilisable. Oui?
C'est exactement le but de l'architecture basée sur les composants. Ils se ressemblent donc plus qu'autre chose.
Je pense que MVC n'est que l'évolution naturelle de OOP et j'ose le dire; une meilleure façon d'organiser vos objets, la séparation des préoccupations et la réutilisation du code.
Je crois que vous confondez des 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 pour travailler avec des bases de données et effectuer des transactions. Il peut définir et vérifier les indicateurs d'état internes, comme s'il y a une vente aujourd'hui, si l'utilisateur se qualifie pour le statut VIP, puis la logique de branche en conséquence quand vient le temps d'accéder, de définir ou de manipuler des données ou de la conduite Ce sont ces indicateurs dont nous parlons lorsque nous discutons des 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 des données pour établir quelles règles métier sont en jeu, un contrôleur doit, à l'OMI, conserver des données d'état d'application plus générales concernant le comportement de l'application, comme si l'utilisateur est connecté ou s'il a un crédit valide. données de la carte en place. Les méthodes du modèle détermineraient l'état de ces choses en premier lieu, mais il est logique que le contrôleur maintienne des indicateurs pertinents pour le flux d'application général s'ils ne s'appliquent pas à la façon dont l'entreprise est gérée ou les transactions de données sont effectué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 de l'état de l'utilisateur jusqu'à ce qu'il soit clair qu'une autre tentative de connexion est en cours.
De même, avec un objet de vue approprié par rapport aux modèles HTML les plus typiques que vous voyez dans la plupart des infrastructures Web côté serveur. Une fois les préférences de couleur de l'utilisateur chargées, ce devrait être la vue qui conserve ces données et s'exécute dessus. Le chargement, la validation et la modification des paramètres sont tous des problèmes de modèle, mais ils ne devraient être des problèmes de modèle qu'une seule fois jusqu'à ce que des changements se produisent.
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 d'agrégation 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 enterrant les données et les détails logiques de l'interaction entre la vue et le modèle. 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.