MVP:プレゼンターモデル通信
-
30-09-2019 - |
質問
MVPデザインパターンのモデルとプレゼンターとの間のコミュニケーションに関するデザインの質問があります。 パッシブビュー.
次の単純なGUIを例として仮定しましょう。私のビューがリストであり、ファイルダイアログを開くためにファイルを選択する可能性があるウィンドウがあります。選択が完了したら、ファイルはリストに追加されます。
私のモデルは、私が開いたすべてのファイルのコレクションになります。
簡単な実装が思い浮かびます(Pseudo 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つの場所で中央に保持する必要がありますか?
解決
この問題はおそらく長い間解決されていますが、検索エンジンからヒットしたので、私の答えは次のとおりです。
Bを使用します。ミキシングを忘れてください。
効率性のためにAのビットを追加したい場合は、モデルに2つの方法が必要です。1つはブール値、もう1つはエミッティングイベントを返します。同期モデル。ADDメソッドがイベントを発する場合、プレゼンターのイベントハンドラーは、そのメソッドコール中にそれらを無視する必要があります。混雑。
でも パッシブビューの私の理解は、プレゼンターがモデルの更新を担当するものであることを示唆しているため、とにかくモデルからファイルを削除するべきであると主張されるかもしれません。これにより、Aの唯一のソリューションへの道が開かれます。
私の最後の答え:Aを使用するか、Bを使用します。混ぜないでください。