我有一个关于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()回调机制。

我现在的问题是: 我是否应该混合更新视图的两种方法(用于同步更新,而B表示异步),或者像解决方案B中提出的那样将其全部保持在一个位置?

有帮助吗?

解决方案

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

使用B.忘记混合。

如果您想为效率添加a的位,则必须有两种模型方法:一个返回布尔值,另一个发射事件。如果同步模型。ADD方法发出事件,则会主持人中的事件处理程序必须在该方法调用过程中忽略它们。乱。

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

我的最后答案:使用A或使用B。不要混合。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top