3

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

さて、この場合、両方の実装は問題なく機能します。ただし、モデルがファイルも監視し、たとえば、ファイルの1つが削除されたときにプレゼンターに通知する必要があると仮定します。次に、とにかくこの種のonModelChanged()コールバックメカニズムが必要です。

私の質問は次のとおりです。ビューを更新するための2つの方法(同期更新の場合はA、非同期の場合はB)を組み合わせるか、ソリューションBで提案されているようにすべてを1か所に集中させる必要がありますか?

4

1 に答える 1

1

この問題はおそらく長い間解決されていますが、私は検索エンジンからそれを見つけたので、ここに私の答えがあります:

Bを使用します。混合を忘れます。

効率を上げるためにAのビットを追加する場合は、モデルに2つのメソッドが必要になります。1つはブール値を返し、もう1つはイベントを発行します。同期Model.addメソッドがイベントを発行する場合、プレゼンターのイベントハンドラーは、そのメソッド呼び出し中にそれらを無視する必要があります。混雑。

ただし、パッシブビューについての私の理解では、プレゼンターがモデルの更新を担当していることを示唆しているため、とにかく、モデルからファイルを削除するのはプレゼンターである必要があると主張される可能性があります。これにより、Aのみのソリューションへの道が開かれます。

私の最終的な答え: Aを使用するか、Bを使用します。混合しないでください。

于 2011-03-10T06:12:41.833 に答える