2010-08-22 71 views
2

我有一个关于MVP设计模式中的模型和演示者之间的沟通的设计问题 - 或者更准确地说,它的派生形式为被动视图MVP:Presenter-Model communication

假设下面这个简单的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建议?

回答

0

这个问题可能是长期解决,但我打它从搜索引擎,所以这里是我的答案:

使用B.算了混合。

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

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

我的最终答案: 使用A或使用B.请勿混用。

相关问题