title: MVP (Model-View-Presenter) in VBA and returning a value
body: <p>I am trying to implement the MVP pattern in VBA for a winform as I wish to be able to reuse the same code for the model/presenter but be able to change the view (winform) for another one easily. I think I have the basics sorted out, however, as the forms are more like "settings" forms rather than say, "interactive" ones, I wish to return a collection of values from the form when it closes, but I am not sure which part (M, V or P) to put this logic in. </p>
  
  <p>I was thinking to put it in the presenter and set it up as a property that I could access from elsewhere.</p>
  
  <p>Here's my code so far (please bear in mind I am a beginner with patterns, and this code is simplified it somewhat):</p>
  
  <p><strong>Presenter:</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>Model:</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>View:</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p>Finally the bit that connects them together:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>So in this case I wish to actually use the values located in the model elsewhere in other code later on. </p>
  
  <p>Should I add a new property to the Presenter part that just returns the model? E.g:</p>
  
  <pre><code>Public Property Get Settings() as IPlanningParametersModel
      Set Settings = model
  End Property
  </code></pre>
  
  <p>I've tried to search for a solution to this, but there aren't many examples of MVP in VB6/VBA (in fact, the only decent one I found was <a href="http://codefornothing.wordpress.com/2007/09/15/model-view-presenter-in-visual-basic-6-part-1/" rel="nofollow" title="here">here</a>), nearly all are in .NET which sometimes doesn't translate that well back to classic VB since they use features not available.</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>After having more time to think and research on this, I think what I need is a way to obtain and set data in the model directly rather than using the storage object that the model is sat upon. For example, in most examples of MVP, the model is a "facade" for a database or other repository which stores its data somewhere. The other parts of the program (i.e. outside the MVP) then query this database to obtain the information that the model was sat on. In this case, nothing accesses the model directly, the flow goes via the database which is almost "independent " of the rest of the program.</p>
  
  <p>In my particular case, I do not really need an underlying database to store this information as I just need to be able to set <em>and</em> get the values that the model holds. </p>
  
  <p><strong>Edit 2</strong></p>
  
  <p>Perhaps I could implement the "database" for the model as a Singleton class and then pass this to the model's constructor when it's initiated? For example:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The <code>DataStore</code> property of the model could use an interface and MySingleton would implement the same interface and then I could then use <code>MySingleton</code> outside of the above code. Does that sound reasonable?</p>
  
  <p>Any other suggestions on this structure are welcome as this is my first attempt!</p>