Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python MVP:演示者模型通信_Python_Design Patterns_Mvp_Passive View - Fatal编程技术网

Python MVP:演示者模型通信

Python MVP:演示者模型通信,python,design-patterns,mvp,passive-view,Python,Design Patterns,Mvp,Passive View,我有一个关于MVP设计模式中模型和演示者之间的沟通的设计问题——或者更准确地说,是从被动视图派生出来的 让我们假设以下简单的GUI为例:我有一个窗口,其中我的视图是一个列表,可以打开一个文件对话框来选择一个文件。一旦我完成选择,该文件将被添加到列表中 我的模型应该是我打开的所有文件的集合 我想到了一个简单的实现,即伪python代码: 解决方案A 在本例中,我知道文件已添加到模型中,因此我相应地更新了视图 另一方面,我可以将文件添加到模型中,然后等待模型通知我已更改,并且演示者必须更新视图,如下

我有一个关于MVP设计模式中模型和演示者之间的沟通的设计问题——或者更准确地说,是从被动视图派生出来的

让我们假设以下简单的GUI为例:我有一个窗口,其中我的视图是一个列表,可以打开一个文件对话框来选择一个文件。一旦我完成选择,该文件将被添加到列表中

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

我想到了一个简单的实现,即伪python代码:

解决方案A

在本例中,我知道文件已添加到模型中,因此我相应地更新了视图

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

解决方案B

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


我现在的问题是:我应该混合使用两种方法来更新视图A以进行同步更新,B以进行异步更新,还是像解决方案B中建议的那样将其全部集中在一个地方?

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

使用B.忘记混合

如果你想增加一点效率,你必须有两个模型方法:一个返回布尔值,另一个发出事件。如果synchronous Model.add方法发出事件,则presenter中的事件处理程序必须在该方法调用期间忽略这些事件。乱七八糟的

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

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

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