VBA中的MVP(Model-View-Presenter)并返回一个值

时间:2014-03-21 16:49:47

标签: winforms vba design-patterns vb6 mvp

我正在尝试在VBA中为winform实现MVP模式,因为我希望能够为模型/演示者重用相同的代码,但能够轻松地更改另一个的视图(winform)。我认为我已经完成了基础知识,因为表格更像是"设置"形式而非说,"互动"其中,我希望在关闭时从表单中返回一组值,但我不确定将该逻辑放入哪个部分(M,V或P)。

我想把它放在演示者中并将其设置为我可以从其他地方访问的属性。

这是我的代码到目前为止(请记住我是模式的初学者,这个代码有点简化):

主讲人:

Private model As IPlanningParametersModel
Private view As IPlanningParameterView

Public Sub Initialise(view As IPlanningParameterView, model As IPlanningParametersModel)
    Set model = model
    Set view = view
End Sub

Public Sub updateViewWthModel()
    Set view.PlanningParameters = model
End Sub

Public Sub updateModelWithView()
    Set model = view.PlanningParameters
End Sub

型号:

Private m_ParamDictionary As Scripting.Dictionary

Implements IPlanningParametersModel

Private Sub Class_Initialize()
    Set m_ParamDictionary = New Scripting.Dictionary
End Sub

Private Sub IPlanningParametersModel_Remove(ByRef Name As String)
    Me.Remove Name
End Sub

Private Sub IPlanningParametersModel_Add(ByRef PlanParam As IPlanningParameter)
    m_ParamDictionary.Add PlanParam
End Sub

Private Function IPlanningParametersModel_Item(ByRef Name As String) As IPlanningParameter
    Set IPlanningParametersModel_Item = m_ParamDictionary.Item(Name)
End Function

查看:

Implements IPlanningParameterView

Private Function IPlanningParameterView_Show(Optional ByVal Modal As Boolean = True)
    If Modal Then Me.Show (vbModal) Else Me.Show (vbModeless)
End Function

Private Function IPlanningParameterView_Hide()
    Me.Hide
End Function

Private Property Let IPlanningParameterView_Caption(ByRef Value As String)
    Me.Caption = Value
End Property       

Private Property Get IPlanningParameterView_PlanningParameters() As IPlanningParametersModel
    'TODO: Cycle through each control in form to obtain configuration
    '      and add IPlanningParametersModel 
End Property

Private Property Set IPlanningParameterView_PlanningParameters() As IPlanningParametersModel
    'TODO: Cycle through each item in IPlanningParametersModel and set
    '      each control in form to reflect the configuration value
End Property

最后将它们连接在一起的位:

Dim model As IPlanningParametersModel
Set model = New PlanningParametersModel

Dim view As IPlanningParameterView
Set view = New FPlanningParameterView

Dim pres As Presenter
Set pres = New Presenter
pres.Initialise view, model

所以在这种情况下,我希望稍后在其他代码中的其他地方使用模型中的值。

我应该向只返回模型的Presenter部件添加新属性吗? E.g:

Public Property Get Settings() as IPlanningParametersModel
    Set Settings = model
End Property

我试图寻找解决方案,但VB6 / VBA中没有很多MVP的例子(事实上,我找到的唯一正确的例子是here),几乎所有的都在.NET中,因为它们使用了不可用的功能,因此有时无法将其转换回经典VB。

修改

在有更多时间思考和研究之后,我认为我需要的是一种直接在模型中获取和设置数据的方法,而不是使用模型所依赖的存储对象。例如,在大多数MVP的例子中,模型是一个" facade"对于在某处存储其数据的数据库或其他存储库。程序的其他部分(即在MVP之外)然后查询该数据库以获得模型所处的信息。在这种情况下,没有任何东西可以直接访问模型,流程通过数据库进行,该数据库几乎是独立的"该计划的其余部分。

在我的特定情况下,我并不需要一个底层数据库来存储这些信息,因为我只需要能够设置获取模型所拥有的值。

修改2

也许我可以实现"数据库"将模型作为Singleton类,然后在它启动时将其传递给模型的构造函数?例如:

Dim model As IPlanningParametersModel
Set model = New PlanningParametersModel
Set model.DataStore = MySingleton

Dim view As IPlanningParameterView
Set view = New FPlanningParameterView

Dim pres As Presenter
Set pres = New Presenter
pres.Initialise view, model

模型的DataStore属性可以使用接口,MySingleton将实现相同的接口,然后我可以在上面的代码之外使用MySingleton。这听起来合理吗?

欢迎任何有关此结构的其他建议,因为这是我的第一次尝试!

1 个答案:

答案 0 :(得分:0)

从演示者公开模型的唯一问题是使用演示者的任何东西都会与它紧密耦合。

我更喜欢我的演示者将事件发送到Event Aggregator然后发布给任何订阅者。这使得一切都松散耦合。

不知道这在VB6中的效果如何,已经很长时间了。但是,如果你走这条路,当模型随着附加到事件的当前模型而改变时,你的演示者会发出一个事件。