L'utilisation D'ObservableList dans JavaFX va-t-elle à l'encontre de la séparation Modèle-Vue-Contrôleur?

j'essaie D'étudier JavaFX parce que je veux l'utiliser comme GUI de mon programme. Ma question est essentiellement conceptuelle:

à ce jour, mon programme est principalement la partie "Modèle" du modèle MVC; c'est-à-dire que presque tout mon code est la représentation OO des abstractions dans le sens des classes, et tout ce code est du code logique.

puisque je ne veux pas être le seul utilisateur de mon programme, je veux ajouter la partie "View" de MVC pour que les gens puissent facilement utiliser et manipuler la partie "Modèle" de mon programme. Pour cela, je veux utiliser JavaFX.

dans mes classes "Model" j'utilise évidemment diverses listes, cartes et autres classes de L'API Java Collections. Afin de permettre aux utilisateurs de mon programme de manipuler ces listes et cartes sous-jacentes, je veux utiliser les interfaces observables(Liste/carte) dans JavaFX.

un exemple concret pour clarifier la situation:

disons que j'ai un MachineMonitor classe qui vérifie toutes les 3 minutes certaines propriétés d'une Machine, comme si la connexion est toujours bonne, la vitesse à laquelle les engrenages tournent, etc. Si certaines inégalités sont rencontrées (disons que la vitesse des engrenages est tombée à une vitesse de 1 tour / s) le MachineMonitor déclenche un moteur RestartMachineEvent.

actuellement j'utilise un ArrayList< MachineMonitor> pour garder une trace de tous les MachineMonitor<!--14 ans. Maintenant, s'étendant à la partie "View" de MVC, je veux que L'utilisateur soit capable de manipuler une vue de table qui affiche la liste de MachineMonitor s pour qu'ils puissent, par exemple, créer et supprimer de nouveaux MachineMonitor de surveiller diverses Machines.

pour que je puisse garder une trace de ce que l'utilisateur de mon programme veut faire (par exemple, créer un MachineMonitor pour la Machine n ° 5 qui vérifie si le tour / sec de la engrenages tombe en dessous de 0,5) - je utiliser un ObservableList< MachineMonitor > comme liste sous-jacente de TableView.

la façon la plus facile de lier le "Modèle" et la " vue "de mon programme serait simplement de changer la classe "modèle" pour avoir une liste observable< MachineMonitor> et pas un ArrayList< MachineMonitor > mais (pour en venir au sujet de la question) je pense que c'est très embrouillé parce qu'il mélange le code "Model" et le code "View".

Un une approche naïve consisterait à utiliser une liste observable< MachineMonitor > pour la TableView et conserver l'utilisation de mon ArrayList< MachineMonitor>. Toutefois, des modifications ont été apportées à la liste D'observations< MachineMonitor > n'affectent pas la liste sous-jacente selon les spécifications JavaFX.

compte tenu de cela, est la meilleure façon de résoudre cette énigme à faire un ChangeListener pour la liste observable< MachineMonitor> qui se "propage" les changements fait à la ObservableList< MachineMonitor > vers L'ArrayList "Model" sous-jacent< MachineMonitor>? Peut-être mettre cela dans une classe appelée MachineMonitorController?

Cette solution ad hoc semble très désordonnée et non idéale.

ma question Est la suivante: Quelle est la meilleure façon de conserver une séparation presque complète entre le "Modèle" et la "vue" dans ce scénario?

11
demandé sur Francesco Menzani 2014-05-14 04:47:37

2 réponses

je suis en désaccord que l'utilisation d'un ObservableList dans votre classe "model" viole la séparation MVC. ObservableList est purement une représentation de données; elle fait partie du modèle et non de la vue. J' (etautres) utiliser les propriétés JavaFX et les collections dans les représentations de modèles dans tous les niveaux de mes applications. Entre autres choses, je souligne comment J'utilise les propriétés JavaFX qui sont (ou peuvent être, au moins) liées à JSF. (Je tiens à préciser que pas tout le monde est d'accord avec l'approche de l'utilisation de propriétés FX du côté du serveur; cependant je ne vois pas vraiment de moyen de faire l'argument qu'ils font d'une certaine façon partie de la vue.)

puisque JavaFX est maintenant une partie à part entière de L'édition Java standard, vous n'ajoutez aucune dépendance supplémentaire non plus. (Un ObservableList n'est pas moins une partie de Java SE qu'un ArrayList.)

aussi, si vous faites

List<MachineMonitor> myNonObservableList = ... ;

ObservableList<MachineMonitor> myObservableList = FXCollections.observableList(myNonObservableList);
myObservableList.add(new MachineMonitor());

la liste observable est soutenue par la liste non observable, donc le changement se produit myNonObservableList trop. Donc vous pouvez utiliser cette approche si vous préférez.

10
répondu James_D 2014-05-14 01:15:16

brièvement, Je ne pense pas que l'utilisation D'ObservableList brise le contrat MVC.

Le reste, vous pouvez lire ou pas comme vous le souhaitez, car il est assez gênant de long.

Dessin Architectural Arrière-Plan

Observables sont utiles dans les architectures de style MVC parce qu'ils fournissent un moyen d'alimenter les données entre les composants MVC par des couplages libres où les classes de modèle et de vue n'ont pas besoin de se référer directement à l'autre, mais peut travailler avec un modèle de données partagées qui communique le flux de données. Ce n'est pas une coïncidence si le motif Observable et le concept d'architecture de style MVC ont tous deux pris naissance à la même époque chez Xerox PARC - les choses sont liées.

Comme indiqué dans le Martin Fowler's GUI architectures, il existe de nombreuses approches différentes pour construire des interfaces graphiques. MVC est juste l'un d'entre eux, un peu le grand-père de tous. Il est agréable de bien comprendre MVC (il est souvent mal compris) et les concepts MVC sont applicables dans de nombreux endroits. Pour votre application, vous devez utiliser le système qui se sent le mieux pour vous plutôt que de suivre rigidement un modèle donné (sauf si vous utilisez un cadre particulier qui applique un modèle donné) et aussi être ouvert à l'adoption de modèles différents dans une application plutôt que d'essayer de tout jeter dans un cadre conceptuel unique.

Java Beans sont une partie fondamentale de presque tous les produits Java programme. Bien que traditionnellement utilisé uniquement dans les applications client, le modèle de l'observateur, à travers PropertyChangeListeners, a été, pour une bonne raison, une partie de l' Java Bean specification depuis sa création. Les éléments observables et contraignants de JavaFX sont une reprise de ce travail antérieur, apprendre à partir de celui-ci pour construire quelque chose qui est à la fois plus pratique à travailler avec et plus facile à comprendre. Peut - être, si les éléments observables et contraignants de JavaFX avaient existé il y a dix ou douze ans dans le le JDK, de tels concepts seraient plus généralement utilisés dans une plus grande variété de bibliothèques et de cadres que quelques cadres GUI purs.

Conseil

je suggère de considérer le MVVM model et d'autres architectures GUI.

si vous voulez un framework dead-easy qui suit un modèle, view, presenter style, definitely give post-combustion.fx à un tour.

je pense que le bon choix de l'architecture dépend de votre demande, de votre expérience et de la taille et de la complexité des problèmes que vous essayez de résoudre. Par exemple, si vous avez un système distribué, alors vous pourriez suivre principes de repos plutôt que (ou en plus) MVC. Quel que soit votre choix, l'architecture devrait vous aider à résoudre le problème (et éventuellement problèmes futurs) et non l'inverse. La sur-architecture d'une solution est un piège courant et est très facile à faire, alors essayez de l'éviter.

Avertissement

une mise en garde à prendre en considération est que les observables fonctionnent nécessairement via des effets secondaires qui peuvent être difficiles à raisonner et peuvent être antithétiques au concept d'isolement. JavaFX dispose de bons outils, comme readonly Objectwrapper et ReadOnlyListWrapper, pour aider à limiter l'impact (contrôle des dommages si vous le souhaitez) sur les observables afin qu'ils ne tournent pas de Travers dans votre système. L'utilisation de tels outils (et des objets immuables) avec insouciance.

apprendre des exemples

pour une application JavaFX simple qui est construite en utilisant des observables, se référer à tic-tac-toe.

pour une bonne façon de structurer une application JavaFX grande et complexe avec des composants basés sur FXML, reportez-vous au code source pour SceneBuilder et SceneBuilderKit. Le code source est disponible dans le JavaFX mercurial source tree, il suffit de la cocher et commencer à apprendre.

Lire sur le JavaFX contrôles de l'INTERFACE utilisateur de l'architecture. Examinez le code source JavaFX controls (e.g. Bouton et ButtonSkin ou ListView et ListViewSkin) pour voir comment des concepts tels que MVC peuvent être appliqués en utilisant des structures JavaFX. Basé sur cet apprentissage, essayez de créer certains de vos propres contrôles personnalisés en utilisant l'architecture que le cadre de contrôle de JavaFX fournit. Souvent, lorsque vous construisez votre propre application, vous n'avez pas besoin de créer vos propres contrôles (au moins ceux qui dérivent le formulaire JavaFX Contrôle). L'architecture JavaFX Controls est spécialement conçue pour prendre en charge la construction de bibliothèques de commandes réutilisables, de sorte qu'elle n'est pas nécessairement adaptée à toutes les utilisations; elle fournit plutôt une démonstration concrète d'une façon éprouvée de faire certaines choses. L'adoption et l'adaptation prouvé les solutions permettent de s'assurer que vous ne réinventez pas des choses inutilement et vous permettent de construire sur une base solide et d'apprendre des épreuves des autres.

Concernant votre Exemple Concret

je vous conseille d'aller avec:

la façon la plus simple de lier le "Modèle" et la " vue "de mon programme serait simplement de changer la classe "modèle" pour avoir une ObservableList et non une ArrayList

Peut-être utiliser un ReadOnlyListWrapper exposer L'ObservableList du MachineMonitor au monde extérieur, de sorte que rien ne peut le modifier indûment.

mettre en place une autre structure qui encapsule la vue (par exemple un ControlPanel et un ControlPanelSkin) et lui fournir une référence à la seule liste observable en lecture de Machinemoniteurs. Le ControlPanelSkin peut encapsuler une vue de table, un graphique ou n'importe quels boutons et widgets visuels que vous voulez utiliser pour l'utilisateur pour surveiller le machine.

L'utilisation d'une telle structure isole efficacement votre vue du modèle. Le modèle ne sait vraiment rien du tout sur L'interface utilisateur et L'implémentation de ControlPanelSkin pourrait être changée pour une représentation visuelle ou une technologie complètement différente sans changer le système de base MachineMonitor.

ce qui précède décrit simplement une approche générale, vous aurez besoin de l'ajuster pour votre exemple spécifique.

11
répondu jewelsea 2014-05-14 04:54:27