2010-08-22 7 views
2

J'ai une question de conception sur la communication entre le modèle et le présentateur dans le modèle de conception MVP - ou plus précisément sa forme dérivée vue passive. Supposons par exemple l'interface graphique simple suivante: J'ai une fenêtre où ma vue est une liste et il y a la possibilité d'ouvrir une boîte de dialogue pour sélectionner un fichier. Une fois ma sélection terminée, le fichier doit être ajouté à la liste.MVP: communication Presenter-Model

Mon modèle doit être la collection de tous les fichiers ouverts.

Une implémentation straight-forward vient à l'esprit (pseudo code python):

Solution A

class Model(): 
    def add(filename): 
     # add file 
     ... 
     # return True if successful 
     return True 

class Presenter(): 
    # event from GUI 
    def onFileOpen(): 
     filename = FileSelectorStuff() 
     isFileAdded = model.add(filename) 
     if isFileAdded: 
      view.insertItem(filename) 

Dans ce cas, je sais que le fichier a été ajouté au modèle et donc mettre à jour la vue en conséquence.

D'autre part, je pourrais ajouter le fichier au modèle, puis attendez que le modèle me notifier qui est a changé et que le présentateur doit mettre à jour la vue, comme ceci:

Solution B

class Model(): 
    def add(filename): 
     # add file 
     ... 
     # alert controller 
     modelChanged(Type.FileAdded, filename) 

class Presenter(): 
    # event from GUI 
    def onFileOpen(): 
     filename = FileSelectorStuff() 
     model.add(filename) 

    # event from model 
    def onModelChanged(type, filename): 
     if type == Type.FileAdded: 
      view.insertItem(filename) 
     elif type == Type.FileRemoved: 
      ... 

maintenant, dans ce cas, les deux implémentations fonctionnent très bien. Mais supposons que le modèle surveille également les fichiers et doit en informer le présentateur lorsque l'un d'entre eux a été supprimé, par exemple. Ensuite, j'ai besoin de ce type de mécanisme de rappel onModelChanged() de toute façon. Dois-je mélanger les deux façons de mettre à jour la vue (A pour les mises à jour synchrones, et B pour asynchrones) ou plutôt tout garder au centre en un seul endroit comme proposé dans la solution B?

Répondre

0

Ce problème est probablement longtemps résolu, mais je l'ai frappé d'un moteur de recherche alors voici ma réponse:

Utilisation B. Oublier le mélange.

Si vous voulez ajouter des bits de A pour l'efficacité, vous devrez avoir deux méthodes pour le modèle: l'une retournant un booléen, les autres émettant des événements. Si la méthode Model.add synchrone émet des événements, le gestionnaire d'événements du présentateur devra les ignorer pendant cet appel de méthode. Désordonné. Ma compréhension de Passive View suggère que le présentateur est celui qui est responsable de la mise à jour du modèle, donc on pourrait soutenir qu'il devrait être celui qui enlève les fichiers du modèle, quoi qu'il en soit. Cela ouvre la voie à une solution unique.

Ma réponse finale: Utiliser A, ou utiliser B. Ne pas mélanger.