111 votes

Pourquoi Qt utilise-t-il mal la terminologie modèle/vue ?

Je pense que la terminologie utilisée dans Qt avec les contrôles modèle/vue est erronée. Sur leur page d'explication ils déclarent avoir simplifié le MVC en MV en fusionnant View et Controller et ils donnent l'image ci-dessous.

picture explaining Qt MVC

Cependant je pense qu'ils ont mal nommé les rôles des objets et je pense que,

  1. Ce qu'ils appellent Vue avec contrôleur fusionné est en fait une Vue seulement.
  2. Ce qu'ils appellent Modèle n'est en fait que Contrôleur.
  3. Si vous voulez vraiment avoir un modèle, il serait quelque part où se trouvent leurs "données".

Je parle de la manière habituelle et saine d'utiliser le composant modèle/vue de Qt dans votre application. Voici les raisons :

  1. Il s'agit typiquement d'un composant Qt qui est utilisé tel quel, sans ajouter de logique de contrôleur spécifique à vos objets).
  2. Ce n'est pas vraiment un modèle, simplement parce que vous devez implémenter plusieurs méthodes Qt comme rowCount, columnCount, data etc. qui n'ont rien à voir avec votre modèle. En fait, on trouve des méthodes typiques de modèle dans les contrôleurs. Bien sûr, vous pouvez implémenter les deux Controller et La logique du modèle ici, mais d'abord ce serait une mauvaise conception du code et ensuite vous fusionneriez le contrôleur et le modèle et non le contrôleur et la vue comme ils le disent.
  3. Comme dit dans la raison 2. si vous voulez séparer la logique du modèle, ce n'est sûrement pas la boîte bleue sur l'image, mais plutôt la boîte "Data" en pointillés (communiquant aux données réelles bien sûr).

Est-ce que Qt se trompe dans sa terminologie, ou est-ce que c'est moi qui ne comprends pas ? (BTW : La raison pour laquelle ce n'est pas une question académique est que j'ai commencé à coder mon projet en suivant leur nomenclature et j'ai rapidement découvert que le code n'était clairement pas correct. Ce n'est qu'après cela que j'ai réalisé que je ne devais pas essayer de mettre la logique du modèle dans ce qu'ils appellent modèle ;-) )

93voto

leemes Points 17391

Réponse courte

Le MVC de Qt ne s'applique qu'à une structure de données . Lorsqu'on parle d'un MVC application vous ne devez pas penser à QAbstractItemModel ou QListView .

Si vous voulez une architecture MVC pour l'ensemble de votre programme, Qt ne dispose pas d'un cadre modèle/vue aussi "énorme". Mais pour chaque liste/arbre de données de votre programme, vous pouvez utiliser l'approche MVC de Qt, qui dispose en effet d'un module contrôleur dans son champ de vision. Le site données est à l'intérieur ou à l'extérieur du modèle ; cela dépend du type de modèle que vous utilisez (sous-classe de modèle propre : probablement à l'intérieur du modèle ; par exemple, QSqlTableModel : à l'extérieur (mais peut-être mis en cache à l'intérieur) du modèle). Pour assembler vos modèles et vos vues, utilisez des classes propres qui implémentent ensuite la fonction logique d'entreprise .


Réponse longue

L'approche modèle/vue et la terminologie de Qt :

Qt fournit de simples vues pour leurs modèles. Ils disposent d'un contrôleur intégré : la sélection, l'édition et le déplacement d'éléments sont ce que, dans la plupart des cas, un contrôleur "contrôle". C'est-à-dire qu'il interprète les entrées de l'utilisateur (clics et déplacements de la souris) et donne les commandes appropriées au modèle.

Qt modèles sont en effet des modèles ayant des données sous-jacentes. Les modèles abstraits ne contiennent bien sûr pas de données, puisque Qt ne sait pas comment les stocker. Mais vous étendre un QAbstractItemModel à vos besoins en ajoutant vos conteneurs de données à la sous-classe et en faisant en sorte que l'interface du modèle accède à vos données. Donc en fait, et je suppose que vous n'aimez pas ça, le problème est que vous Vous devez programmer le modèle, c'est-à-dire la façon dont les données sont accédées et modifiées dans votre structure de données.

Dans la terminologie MVC, le modèle contient à la fois le données et le logique . Dans Qt, c'est à vous de décider si vous incluez ou non une partie de votre logique commerciale dans votre modèle ou si vous la placez à l'extérieur, en tant que "vue" à part entière. Ce n'est même pas clair ce que l'on entend par logique : Sélectionner, renommer et déplacer des éléments ? => déjà implémenté. Faire des calculs avec eux ? => à l'extérieur ou à l'intérieur de la sous-classe du modèle. Stocker ou charger des données à partir d'un fichier ou vers un fichier ? => mettre à l'intérieur de la sous-classe modèle.


Mon opinion personnelle :

Il est très difficile de fournir un bon et système MV(C) générique à un programmeur. Parce que dans la plupart des cas, les modèles sont simples (par exemple, uniquement des listes de chaînes), Qt fournit également un QStringListModel prêt à l'emploi. Mais si vos données sont plus complexes que des chaînes de caractères, c'est à vous de voir comment vous voulez représenter les données via l'interface modèle/vue de Qt. Si vous avez, par exemple, une structure avec 3 champs (disons des personnes avec un nom, un âge et un sexe), vous pouvez affecter les 3 champs à 3 colonnes différentes ou à 3 rôles différents. Je n'aime pas les deux approches.

Je pense que le cadre modèle/vue de Qt n'est utile que lorsque vous voulez afficher structures de données simples . Il devient difficile à manipuler si les données sont de type types personnalisés ou structuré non pas en arbre ou en liste (par exemple, un graphe). Dans la plupart des cas, les listes sont suffisantes et même dans certains cas, un modèle ne devrait contenir qu'une seule entrée. En particulier si vous voulez modéliser une seule entrée ayant différents attributs (une instance d'une classe), le cadre modèle/vue de Qt n'est pas le bon moyen de séparer la logique de l'interface utilisateur.

Pour résumer, je pense que le cadre modèle/vue de Qt est utile si et seulement si vos données sont visualisées par l'un des éléments suivants Les widgets de visualisation de Qt . Il est totalement inutile si vous êtes sur le point d'écrire votre propre visualiseur pour un modèle ne contenant qu'une seule entrée, par exemple les paramètres de votre application, ou si vos données ne sont pas de types imprimables.


Comment ai-je utilisé le modèle/la vue de Qt dans une (plus grande) application ?

J'ai écrit une fois (en équipe) une application qui utilise plusieurs modèles Qt pour gérer les données. Nous avons décidé de créer un DataRole pour contenir les données réelles qui étaient d'un type personnalisé différent pour chaque sous-classe de modèle. Nous avons créé une classe de modèle externe appelée Model contenant tous les différents modèles Qt. Nous avons également créé une classe de vue externe appelée View contenant les fenêtres (widgets) qui sont connectées aux modèles dans le cadre de l'activité de l'entreprise. Model . Cette approche est donc un MVC Qt étendu, adapté à nos propres besoins. Les deux sites Model et View Les classes elles-mêmes n'ont rien à voir avec le MVC de Qt.

Où avons-nous mis le logique ? Nous avons créé des classes qui effectuaient les calculs réels sur les données en lisant les données des modèles sources (lorsqu'ils étaient modifiés) et en écrivant les résultats dans les modèles cibles. Du point de vue de Qt, ces classes logiques seraient des vues, puisqu'elles se "connectent" aux modèles (pas de "vue" pour l'utilisateur, mais une "vue" pour la partie logique de l'application).

Où sont les contrôleurs ? Dans la terminologie MVC originale, les contrôleurs interprètent les entrées de l'utilisateur (souris et clavier) et donnent des commandes au modèle pour qu'il effectue l'action demandée. Puisque les vues Qt interprètent déjà les entrées de l'utilisateur, comme renommer et déplacer des éléments, cela n'était pas nécessaire. Mais ce dont nous avions besoin, c'était d'une interprétation de l'interaction de l'utilisateur qui aille au-delà des vues Qt.

82voto

Tilo Points 1739

Je suis d'accord avec vous pour dire que la dénomination de Qt est trompeuse. Cependant, à mon avis, le problème n'est pas propre à Qt, mais est partagé par tous les frameworks qui nous permettent d'adhérer au principe de l'utilisation des noms de domaine. séparation des préoccupations lors de l'implémentation de nos interfaces utilisateur. Lorsque quelqu'un propose un tel cadre et trouve un bon moyen de séparer les "choses", il se sent toujours obligé d'avoir des modules qu'il appelle "Modèle" et d'autres qu'il appelle "Vue". Au fil des années, j'ai travaillé avec ces frameworks :

  • MFC
  • Qt
  • Swing
  • SWT
  • WPF avec MVVM

Si vous comparez la façon dont les termes "Modèle" et "Vue" sont utilisés dans ces frameworks, et quelles sont les responsabilités des classes dans la "Vue", le "Modèle" et le "Contrôleur" (s'il y en a un), vous constaterez qu'il y a de très grandes différences. Il serait certainement utile de disposer d'une comparaison des différents concepts et terminologies, afin que les personnes passant d'un framework à un autre aient une chance de rester saines d'esprit, mais cela nécessiterait beaucoup de travail et de recherche. Une bonne lecture est celle de Martin Fowler. vue d'ensemble .

Comme il y a tellement d'idées différentes sur ce que un Le modèle MVC peut ressembler à quoi, lequel est correct ? À mon avis, il faut se tourner vers les personnes qui ont inventé le MVC lorsque l'on veut savoir comment il est censé être mis en œuvre "correctement". Dans le papier original smalltalk il est dit :

La vue gère la sortie graphique et/ou textuelle sur la partie de l'affichage en mode point qui est allouée à son application. Le contrôleur interprète les entrées de la souris et du clavier de l'utilisateur, et commande au modèle et/ou à la vue d'effectuer les changements appropriés. Enfin, le modèle gère le comportement et les données du domaine d'application, répond aux demandes d'informations sur son état (généralement en provenance de la vue), et répond aux instructions de changement d'état (généralement en provenance du contrôleur).

À la lumière de ces éléments, je répondrais à vos trois principales préoccupations de la manière suivante :

  1. En fait, un composant Qt "gère la sortie graphique [...]", et "interprète les entrées de la souris et du clavier", de sorte qu'il pourrait effectivement être appelé vue et contrôleur fusionnés par rapport à la définition ci-dessus.
  2. Je suis d'accord pour dire que vous êtes/seriez obligé de fusionner Contrôleur et Modèle (toujours par rapport à la définition ci-dessus).
  3. Je suis d'accord, encore une fois. Le modèle ne devrait gérer que les données du domaine d'application . C'est ce qu'on appelle des "données". Il est clair que le traitement des lignes et des colonnes, par exemple, n'a normalement rien à voir avec le domaine de nos applications.

Où cela nous mène-t-il ? À mon avis, il est préférable de comprendre ce que Qt veut vraiment dire quand les termes "Model" et "View" sont utilisés et d'utiliser ces termes à leur manière pendant que nous programmons avec Qt. Si vous continuez à être dérangé, cela ne fera que vous ralentir, et la façon dont les choses sont organisées dans Qt permet une conception élégante - ce qui pèse plus lourd que leurs "mauvaises" conventions de dénomination.

13voto

arnt Points 1750

La terminologie n'est pas bonne ou mauvaise, elle est utile ou inutile.

Vous pourriez changer un peu la question et demander pourquoi Qt n'est pas plus favorable aux MVC. La réponse à cette question est que les premiers développeurs de Qt pensent que le découplage entre V et C dans les applications GUI donne lieu à de mauvais Vs et Cs. La conception de QWidget tente de simplifier l'interaction entre l'entrée de la souris et les décisions de sortie des pixels, et vous pouvez voir comment ce n'est pas la voie vers MVC.

3voto

Dmitry Points 21

La fonction du modèle étant de répondre aux demandes d'information, je pense qu'il n'y a rien de mal à définir des méthodes telles que rowCount , columnCount etc. Je pense que le modèle est une sorte d'enveloppe pour la source de données (qu'il s'agisse d'une table SQL ou d'un simple tableau), il fournit des données sous une forme standard, et vous devez définir des méthodes en fonction de la structure de votre source de données.

2voto

Chris Morlier Points 134

Je pense que leur terminologie est correcte... bien que dans les applications réelles, je trouve qu'il peut être très facile de brouiller les lignes entre le modèle, la vue et le contrôleur en fonction de votre niveau d'abstraction : la vue d'un niveau peut être le modèle d'un niveau supérieur.

Je pense que la confusion vient de leur classe QAbstractModelItem. Cette classe n'est pas un élément de modèle, mais plutôt une interface vers un modèle. Pour que leurs classes de vue s'interfacent avec le modèle, ils ont dû créer une interface abstraite générique pour le modèle. Toutefois, un modèle peut être un élément unique, une liste d'éléments, un tableau de 2 dimensions d'éléments ou plus, etc. Il faut admettre que cela rend les éléments du modèle assez complexes, et le code de liaison pour le faire fonctionner avec un modèle réel semble pousser la métaphore un peu loin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X