MVP:Presenter-Model通信

时间:2010-08-22 13:28:10

标签: python design-patterns mvp passive-view

我对MVP设计模式中模型与演示者之间的沟通有一个设计问题 - 或者更确切地说,它是从被动视图中衍生出来的。

让我们假设以下简单的GUI作为示例:我有一个窗口,我的视图是一个列表,并且可以打开文件对话框来选择文件。完成选择后,文件将附加到列表中。

我的模型应该是我打开的所有文件的集合。

想到一个简单的实现(伪python代码):

解决方案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)

在这种情况下,我知道该文件已添加到模型中,因此我相应地更新了视图。

另一方面,我可以将文件添加到模型中,然后等待模型通知我已更改并且演示者必须更新视图,如下所示:

解决方案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:
            ...

现在,在这种情况下,两种实现都可以正常工作。但是,我们假设该模型还监视文件,并且需要告诉演示者其中一个文件是否已被删除。然后我还需要这种onModelChanged()回调机制。

我现在的问题是:我应该混合使用两种方式来更新视图(A用于同步更新,B用于异步),或者更确切地说将其保留在解决方案B中建议的一个位置?

1 个答案:

答案 0 :(得分:0)

这个问题很可能已经解决了,但是我从搜索引擎中找到了它,所以这是我的答案:

使用B.忘记混合。

如果要为效率添加A位,则必须为模型提供两种方法:一种返回布尔值,另一种返回事件。如果同步Model.add方法发出事件,那么演示者中的事件处理程序将不得不在该方法调用期间忽略它们。凌乱。

然而我对被动视图的理解表明,Presenter是负责更新模型的人,因此可能会认为应该是从模型中删除文件的人。这为A唯一的解决方案铺平了道路。

我的最终答案: 使用A,或使用B.不要混用。