MVC

MVC est un raccourci pour "Modèle, Vue, Contrôleur", et c'est une technique de conception fréquemment employée par les programmes orientés objets pour faciliter la modularité, la fléxibilité et la réutilisation. Comme vous pouvez le supposer, cela implique de séparer les objets en une séquence d'interaction particulière en 3 catégories, chacune d'elles supportant une interface à but général à travers laquelle les 2 autres la connaissent.

La plupart des programmes intégrent les MVC en plus ou moins grande quantité pour la forme, mais Berlin l'adopte comme une technique centrale à travers tous ses systèmes, aussi bien en interne que lros de la communication avec des applications dans des porcessus séparés. Il est très important de comprendre comment et pourquoi nous utilisons le modèle MVC.

Pourquoi séparer ?

La séparation d'un programme en Modèle, Vue, et Contrôleur possède un grand nombre d'avantages dont on va parler en attaquant ces 3 concepts tout de suite. Tout d'abord et principalement, il fournit un ensemble naturel de frontières d'encapsulation, qui permet de reduire les interdépendances du programme et les interactions, et donc reduit les erreurs et améliore la compréhension du programme. Ensuite, la séparation encourage les relations plusieurs-plusieurs à travers la frontière des composants, ce qui (en fin de compte) est implicite dans la plupart des besoins des programmes dès le début. Par exemple, en ayant un modèle séparé des contrôleurs, cela facilite énormément l'adaptation d evotr emodèle pour des manipulation simultanées par de multiples parties, telles que des utilisateurs distants ou des moteurs de scripts, ou par des manipulations à travers des types d'événements précédemment inconnu. De même, avoir des composants de vues séparés, facilite la production de multiples vues d'un même modèle (pour des interactions simultanées par l'intermédiaire de différentes représentations) et l'adaptation vers une nouvelle représentation. Dans notre cas, la séparation MVC est aussi un ensemble idéal de limites le long desquelles on peut se déplacer entre les langages de programmation ou les espaces d'adresse de processus (comme cela est permis par CORBA). une pratique commune pour stocker tout ou partie d'un modèle de donnée dans une application cliente, et la plupart des contrôleurs et des composants de modèle dans le serveur d'affichage où ils un accès à haut débis à l'affichage et au périphérique d'entrée.

Espace d'application contre espace de représentation

La séparation mentionnée ci-dessus entre les espaces d'adressage du processus fait référence, en général, à une séparation client/serveur. Dans beaucoup de systèmes de fenêtrage, le client stocke la majorité des structures de données, et le serveur d'affichage stocke un minimum de données requis pour représenter l'état de son affichage. Dans berlin, nous avons beaucoup plus de flexibilité pour les endroits de stockage, pour deux raisons : le protocole de communication client/serveur est généré automatiquement par le compilateur de stub de CORBA, donc il est très facile d'ajouter des concepts sémantiquement riche pour son "vocabulaire" ; et le serveur d'affichage n'a pas de privilèges de niveau du sytème d'exploitation particuliers, donc il peut être beaucoup plus léger sur le sort des extensions dynamiques qu'il charge. La flexibilité qui en résulte permet de charger la plupart du code de représentation d'une métaphore d'une interface utilisateur dans le serveur d'affichage, et d'"attacher" simplement les modèles d'application, tournant dans des processus séparés, aux UI aux endroits appropriés. Cette séparation entre l'"espace de représentation" et l'"espace d'application" nous donne des avantages concrets : les applications écrits avec des langages de script simple on accès aux puissants composants de l'UI, les méchanismes d'accessibilités et les préférences utilisateur (comme les "thèmes") ont des effets plus standard sur les applciations, le traffic réseau est grandement reduits, de multiples représentations peuvent être attachées à la même applications de façon relativement facile, et les personnes qui créent les applications n'ont pas à se préoccuper autant du périphérique sur lequel ils dessinent.

Les modèles dans l'espace d'application

Les modèles supportent une interface commune, que nous avons appelé Subject pour que cela reste famillier aux programmeurs Java. Cela inclus les opérations d'addition et de suppressions des Observers (tels que les Views), aussi bien qu'une méthode de notification commune qu'un client (ou le modèle lui-même) appelerait lorsque les observeurs doivent être notifiés d'une modification du modèle. De plus, la plupart des modèles sous-classent un petit peu l'interface Subject pour fournir des accesseurs pour leur type de données concrets.

Un cas particulier : les contrôleurs

Un bon exemple qui illustrera le but du paragdime du MVC est la séparation des données et la présentation dans les contrôleurs. Comme nous l'avons vu dans le chapitre précédent, le travail des contrôleurs est de passer en revue les événements d'entrées. En fait, ils interprètent l'événement et la projection pour les changements d'état (observables). Les événements en tant que tels sont considérés comme des significations particulières entre le serveur et le contrôleur pour notification. Par conséquent, les changements de focus et la réception de l'événement n'est pas visible pour le monde externe. Cependant, le contrôleur est fortement collé au modèle, qui représente son état. En fait, ce couplage est si collé que nous avons choisi de l'implémenter dans le même objet. C'est un Telltale (rapporteur) à l'intérieur du contrôleur qui sert son but. Une implémentation typique d'un contrôleur positionnera les drapeaux appropriés dans ce rapporteur (telltale) et sont alors observables. En d'autres mots - vous demanderez jamais au contrôleur s'il possède le focus clavier ou s'il possède une attache d'un périphérique de position. Vosu demandez si il est actif, pressé, choisi, etc. Pour des boutons par exemple, vous utiliserez typiquement des cadres ou des résumés pour refléter ces drapeaux d'état. Ce découplage possède l'avantage de pouvoir personnaliser le comportement - c'est-à-dire la projection des événements sur leur drapeaux sémantiques - et par conséquent avoir une liberté d'adaptation de l'interface qu'il vous est nécessaire. Voici les drapeaux prédéfinis déclarés dans l'interface Telltale :

Table 1-4. Drapeaux du rapporteur prédéfinis

Activé (enabled)Le contrôleur est activé s'il peut recevoir des événements
Actif (active)Un clic de bouton ou la touche Entrée appuie dessus a button click or the Enter key would press it
Pressé (pressed)Le contrôleur est en train d'être pressé
Choisi (chosen)Un drapeau utilisé dans un éléments basculable
Fonctionne (running)Indique qu'une commande associée est en cours d'éxécution
......

Exemples concrets

Ici nous donnons quelques exemples de Modèles que berlin a pre-fabriqué pour observer et modifier. Ils devrait aider à assimiler l'idée de Modèle, si ce n'est pas encore clair.

Valeurs limitées

Une BoundedValue est une valeur à virgule flotante double précision avec des incréments nommés incorporés. Les incréments sont important, parce qu'ils permettent de construire des contrôleurs à but général qui "contourne" le domaine numérique sans avoir besoin de se préoccuper exactement de la largeur ou de l'incrément du pas. Lorsque la valeur est modifiée, le BoundedValue contrôle la modification pour s'assurer qu'il représente bien une différence numérique réelle (cette étape est importante pour empêcher des boucles de notification) puis le notifie à tous les observeurs.

Les rapporteurs

Les Telltales représentent des ensembles de drapeaux, chacun d'eux pouvant être, de façon indépendante, testés, définis ou rendu indéfini. Les drapeaux sont nommés pour correspondre aux états "basculables" communes que les contrôles de l'UI peuvent affecter, tel que activé, visible, actif, choisie, fonctionnant, en transfert, choisissable, bascule. Ces noms choisies dans le but de permettre aux rapporteurs (Telltales) d'être, entre autre choses, utilisés pour modèliser l'état du contrôleur lui-même.

Chaînes de caractères

Les chaînes de caractères, l'exemple le plus classique que nous connaissons et apprécissions, sont un petit peu plus complexe dans berlin puisque nous utilisons le codage texte unicode en interne. Spécialement, à chaque fois qu'un texte est changé dans un buffer de chaîne modifiable, nous devons re-découper le texte en unités indivisibles (qui ne correspondant pas forcement au caractère), puis parcourir séquentiellement chaque unité qui a été changé en refaisant le rendu dans des glyphes. Cette fonctionnalité seul exclus de faire une correspondance 1:1 entre le "modèle" texte et ses toutes autres vues ou contrôles.

Les vues dans l'espace de répresentation

Comme décrits précédemment, les vues des modèles (ou "espace de représentation") reside principalement à l'exterieur du processus du serveur d'affichage. Bien qu'il soit possible d'attacher des noeuds de "vues" distants au graphe de scène, 2 raisons empêchent que cela arrive dans les cas classiques : CORBA est intressèquement lent lors de la création d'un grand nombre d'appel inter-processus, et procéder ainsi émpécherait aussi toutes préférences utilisateurs qui pourrait affecter l'apparence concrète de la vue. Puisqu'une partie de notre but est de permettre aux utilisateurs de renforcer leurs préférences à travers tous les éléments de l'UI, le second problème est considéré très sérieux. On recommande de laisser le serveur construire les vues à votre place autant que possible.

Exemples concrets

Ici nous décrivons des vues particulières de modèles abstraits. Cela aidera à comprendre le concept de View.

Boutons radios

Les boutons radios sont un vue particulière d'un ensemble de raporteurs mutuellement exclusif. La sélection de l'un desélectionnera n'importe quel autre. Ils sont habituellement présentés avec un ensemble de libellé, des cercles ou des rectangles en biseaux, si possible avec des marques dessinées dessus.

Ascenseurs

Les ascenseurs sont une vue spécifique d'un BoundedValue.

Les contrôleurs : relais des espaces