views:

57

answers:

0

Hey there,

I have a design question about the communication between the model and the presenter in the MVP design pattern -- or more accurately its derived form the passive view.

Let's assume the following simple GUI as an example: I have a window where my view is a list and there is the possibility to open a file dialog to select a file. Once I've finished my selection the file shall be appended to the list.

My model shall be the collection of all files I have opened.

A straight-forward implementation comes to mind (pseudo python code):

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)

In this case I know that the file was added to the model and thus I update the view accordingly.

On the other hand I could add the file to the model, and then wait for the model to notify me that is has changed and that the presenter has to update the view, like so:

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:
            ...

Now, in this case both implementations work just fine. But let's assume that the model also monitors the files and needs to tell the presenter when one of them has been deleted, for example. Then I need this kind of onModelChanged() callback mechanism anyway.

My question now is: Should I mix the two ways for updating the view (A for synchronous updates, and B for async) or rather keep it all central in one place as proposed in solution B?