2010-02-24 8 views
8

Je cherche un article ou un tutoriel qui donne un exemple de ce à quoi devrait ressembler un pattern MVC (2.0?) À jour avec le framework Swing.Exemple de Swing MVC à jour + Question

De plus, étant plus habitué à une architecture en couches, j'aimerais savoir comment les objets de domaine ou les POJO s'intègrent dans l'image. Ai-je raison de supposer qu'ils sont séparés et appelés par le modèle? En ce qui concerne le modèle lui-même, y a-t-il des conventions largement utilisées en termes de regroupement de classes en paquets?

TIA,

James P.

Répondre

26

C'est une grande question. Je partagerai quelques réflexions avec vous sur ce sujet et je verrai ce qui en sortira.

Swing est plus Modèle-> Voir que Modèle-> Vue-> Contrôleur. Le problème avec Model-> View est que typiquement les applications Swing sous-classent un objet View, et que les objets deviennent à la fois la View et le Controller pour cette vue. Heures supplémentaires dans les grandes applications cela conduit à beaucoup de problèmes et de code spaghetti.

Ce que je fais maintenant depuis plusieurs années est de créer un objet séparé appelé un contrôleur qui ne prolonge pas les classes d'interface utilisateur. C'est un vieil objet simple à cet égard. Ce contrôleur sera chargé d'instancier les composants de niveau supérieur pour la vue, de connecter les écouteurs à la vue pour répondre à l'utilisateur, et de se retourner et de faire des appels sur le modèle pour accomplir le travail.

La vue sous-classe Swing. La vue est responsable de la réponse aux événements de souris, aux événements de clavier, etc. Tout type d'événement spécifique à Swing est géré dans la vue. Il fournira également des méthodes de haut niveau pour mettre à jour la vue que le contrôleur utilisera pour rappeler pour mettre à jour l'interface utilisateur. Les modèles de balançoires classiques font également partie de la vue parce que votre choix de composants est très lié aux modèles que vous utiliserez. La vue est également responsable de l'envoi d'événements de haut niveau au contrôleur, et le contrôleur est chargé de répondre à ces événements de haut niveau. Ces événements peuvent être UserEvent.ADD, UserEvent.EDIT, AuthenticationEvent.LOG_IN, AuthenticationEvent.LOG_OUT, etc. Ces événements sont des événements d'application et en lisent davantage sur ce qu'un responsable de produit peut reconnaître. Le contrôleur ne répond pas à la souris, au ChangListener, etc. J'ai réellement construit mon propre framework EventDispatch et Event pour ceux-ci car Swing est si difficile à étendre et à utiliser efficacement. La vue fonctionne quelque chose comme:

public void mouseClicked(MouseEvent evt) { 
    User u = getUserAt(evt.getPoint()); 
    dispatch(new UserEvent(UserEvent.EDIT, u)); 
} 

Dans mon contrôleur j'ai des méthodes simples qui sont câblées à ces événements. Voici peut-être un exemple de:

@EventCallback(command = "exit") 
public void exit(AppEvent evt) { 
    onExit(); 
} 

@EventCallback(command = "help.about") 
public void showAbout(AppEvent evt) { 
    audioFinderFrame.showAboutDialog(engine.getLicenseInfo()); 
} 

@EventCallback(command = MediaSourceEvent.START_REFRESH) 
public void refreshStarted(final MediaSourceEvent event) { 
    if(frame != null) frame.refreshMediaSource(event.getSource(), true); 
} 

Les annotations sont une extension que je dois ajouter des méthodes d'écouteur d'événement rapidement à une source EventDisptach. Mais, le point étant que chaque méthode sur le contrôleur est invoquée à partir de la vue en utilisant des événements de haut niveau. Ceci permet au contrôleur d'être quelque peu isolé de la façon dont la vue est affichée. La méthode de connexion du contrôleur n'a pas à s'inquiéter des composants qui composent la vue. Il reçoit juste un événement et effectue le travail. Le contrôleur est en charge du flux de l'application. Comme le système d'événements est séparé du Swing I, il le réutilise dans les couches du modèle afin que le modèle puisse renvoyer les événements au contrôleur et que le contrôleur puisse relayer ces modifications dans l'interface utilisateur.

Le modèle et le contrôleur sont des POJO. Ils comprennent les événements, mais c'est tout. Le modèle est la logique de l'application, y compris un niveau de DAO, des services pouvant effectuer des tâches d'arrière-plan, toute couche de service qui parle au serveur et des objets que la plupart des gens pourraient qualifier de DTO.Je ne prescrive pas à l'idée qu'un DTO ne devrait être que de simples structures getter/setter. J'autorise une certaine logique parce que c'est la seule chose qui flotte entre toutes les couches. Parce que chaque couche a accès à eux, ils fournissent un bon endroit pour centraliser la logique que chaque couche peut réutiliser. La vue, le contrôleur et le modèle peuvent accéder à ces méthodes, alors pourquoi ne pas les placer dans l'objet qui se déplace entre eux.

Généralement, cette logique est plus proche de la logique métier ou de la logique de maintenance du modèle. Je fais attention à coupler des systèmes d'architecture plus grands à ces méthodes. Ces méthodes ne vont pas parler à la base de données, ou appeler les méthodes côté serveur afin qu'ils ne portent pas de références à des pièces d'architecture plus grande. Ils ont tous les avantages des DTO: légères, facilement constructibles, peu dépendantes, mais conservent les principes de la conception orientée objet: encapsulation, réutilisation et dissimulation d'informations.

J'ai également commencé à utiliser Spring pour câbler les parties du modèle avec leurs dépendances et les dépendances que le contrôleur a sur le modèle. J'ai trouvé que ce modèle fonctionne très bien et c'est beaucoup plus agréable que de ne pas l'utiliser. Il est également agréable d'avoir accès à des technologies comme les modèles Spring JDBC et les modèles JMS si j'utilise ces technologies. Mais c'est facultatif.

Je ne réutilise jamais les contrôleurs. Les contrôleurs sont la chose la plus spécifique dans votre système, et les généralités ne font que les rendre plus difficiles à maintenir. Les généralités appartiennent à la vue et au modèle, car elles facilitent le développement. Donc, les modèles de conception ont tendance à se trouver sur ces côtés, mais rarement dans le contrôleur. Les contrôleurs sont des appels de méthode simples dans les deux sens.

J'ai trouvé que cela a permis de créer des interfaces utilisateur Swing plus faciles et plus simples. Je suis moins susceptible d'entrer dans des boucles d'événements infinis en écoutant et en manipulant deux contrôles à la fois. Je trouve aussi qu'il est plus facile de tester et de casser le système parce qu'une grande partie de ma logique existe en dehors de la portée de Swing. Cela rend les tests fonctionnels possibles sans une énorme boîte à outils essayant de simuler des clics de souris, etc.

Il n'y a pas beaucoup de code ici pour illustrer désolé, mais j'espère que cela aidera.