Existe-t-il une collection de directives de conception communément acceptées pour séparer les classes Model des classes View / Controller dans une application Java Swing? Je ne suis pas tellement préoccupé par le fait que le View / Controller ne sait rien du modèle comme l'inverse: j'aimerais concevoir mon modèle pour n'avoir aucune connaissance de quoi que ce soit dans javax.swing. Idéalement, il devrait avoir une API simple lui permettant d'être piloté par quelque chose d'aussi primitif qu'une CLI. Ce devrait être, en gros, un "moteur".
La communication des événements GUI au modèle n'est pas trop difficile - les Action Performers peuvent appeler l'API du modèle. Mais qu'en est-il lorsque le modèle effectue ses propres changements d'état qui doivent être reflétés dans l'interface graphique? C'est à cela que sert «l'écoute», mais même «être écouté» n'est pas entièrement passif; cela nécessite que le modèle sache comment ajouter un écouteur.
Le problème particulier qui m'a fait réfléchir implique une file d'attente de fichiers. Du côté de l'interface graphique, il y a un DefaultListModel
derrière un JList
, et il y a des éléments graphiques pour choisir des fichiers dans le système de fichiers et les ajouter à la JList. Du côté du modèle, il souhaite extraire les fichiers du bas de cette "file d'attente" (les faisant disparaître de la JList) et les traiter d'une manière ou d'une autre. En fait, le code Model est déjà écrit - il maintient actuellement une ArrayList<File>
et expose une add(File)
méthode publique . Mais je ne sais pas comment faire fonctionner mon modèle avec le View / Controller sans quelques modifications lourdes spécifiques au Swing.
Je suis très nouveau dans la programmation Java et GUI, ayant toujours fait de la programmation "batch" et "back-end" jusqu'à présent - d'où mon intérêt à maintenir une division stricte entre le modèle et l'interface utilisateur, si c'est possible et si cela peut être enseigné.
Réponses:
Il n'y a pas de directives de conception communément acceptées (c'est-à-dire de facto ) pour MVC. Ce n'est pas si difficile que ça de le faire vous-même, mais cela nécessite une certaine planification de vos cours et beaucoup de temps et de patience.
La raison pour laquelle il n'y a pas de solution définitive est qu'il existe plusieurs façons de faire du MVC, toutes avec leurs avantages et leurs inconvénients. Soyez donc intelligent et faites ce qui vous convient le mieux.
Pour répondre à votre question, vous souhaitez également dissocier le contrôleur de la vue (vous pouvez donc utiliser la même logique de règle métier pour une application Swing et dans l'application console). Dans l'exemple Swing, vous voulez découpler le contrôleur du
JWindow
widget et de n'importe quel widget dans Swing. La façon dont je le faisais (avant d'utiliser les cadres réels) consiste à créer une interface pour la vue que le contrôleur utilise:Pour cette solution lors du démarrage, vous devez enregistrer le contrôleur dans la vue.
Ce pourrait être une bonne idée de créer un conteneur IoC pour faire toute la configuration pour vous à la place.
Quoi qu'il en soit, de cette façon, vous pouvez implémenter des vues console uniquement, en utilisant les mêmes contrôleurs:
La partie amusante est de savoir comment gérer les événements. J'ai implémenté cela en laissant la vue s'enregistrer auprès du contrôleur à l'aide d'une interface, cela se fait en utilisant le modèle Observer (si vous utilisez .NET, vous utiliseriez des gestionnaires d'événements à la place). Voici un exemple d'un simple "observateur de documents", qui signale quand un document a été enregistré ou chargé.
De cette façon, la vue peut se mettre à jour correctement car elle s'abonne aux mises à jour du document. Il suffit de mettre en œuvre l'
DocumentObserver
interface:J'espère que ces exemples motivants vous donneront quelques idées sur la façon de le faire vous-même. Cependant, je vous conseille fortement d'envisager d'utiliser des frameworks en Java qui font la plupart des choses pour vous, sinon vous finirez par avoir beaucoup de code standard qui prend beaucoup de temps à écrire. Il existe quelques plates-formes client enrichi (RCP) que vous pouvez utiliser pour implémenter certaines des fonctionnalités de base dont vous avez le plus probablement besoin, telles que la gestion des documents à l'échelle de l'application et une grande quantité de gestion des événements de base.
Il y a un couple auquel je peux penser de ma tête: Eclipse et Netbeans RCP.
Vous devez encore développer des contrôleurs et des modèles pour vous-même, mais c'est pourquoi vous utilisez un ORM. L'exemple serait Hibernate .
Les conteneurs IoC sont cool'n all, mais il existe également des cadres pour cela. Tels que Spring (qui gère également les données entre autres).
la source
Je pense que parfois nous devons faire des compromis
Comme vous le dites, ce serait formidable si nous pouvions propager la notification de changement implicitement sans que l'objet observé ait une infrastructure explicite pour cela. Pour les langages impératifs courants comme Java, C #, C ++, leur architecture d'exécution est trop légère, pour l'instant, de toute façon. J'entends par là que cela ne fait pas partie de la spécification linguistique pour le moment.
Dans votre cas particulier, je ne pense pas que ce soit exactement une mauvaise chose de définir / utiliser une interface générique comme INotifyPropertyChanged (comme en c #), car cela n'est pas automatiquement couplé à une vue de toute façon - cela dit simplement que si je change, Je vais te le dire .
Encore une fois, je conviens que ce serait formidable si nous n'avions pas à définir la notification de changement nous-mêmes, mais là encore, si elle était implicite pour toutes les classes, elle pourrait entraîner des frais généraux.
la source