#StackBounty: #excel #vba Application specific implementation of a class method

Bounty: 50

I have a library (add-in) with a class that is used in a few small applications. I want to provide a Save method to that class, which
will depend on the application that is running.
To solve it I am trying to use a strategy pattern(I might be misunderstanding the pattern), but my understanding of the subject is lacking. At runtime I am providing a strategy class that will handle the saving. Common class exposes a Save method that relays it to the provided strategy class. But to keep consistency it appears to me that common class have to implement the strategy interface as well.

IRecord (Common Class) Interface:

Public Function DoSomething(): End Function
Public Function SetStrategy(ByVal Strategy As IDatabaseStrategy): End Function

Record (Common Class) implementation:

Private RecordStrategy As IDatabaseStrategy
Implements IRecord
Implements IDatabaseStrategy 'Implements this interface to have Save method
Private Function IRecord_DoSomething():
    'does whatever the class is supposed to do
End Function
Private Function IRecord_SetStrategy(ByVal Strategy As IDatabaseStrategy)
    Set RecordStrategy = Strategy
End Function
Private Function IDataBaseStrategy_Save()
    RecordStrategy.Save
End Function

Strategy Interface and Implementation:

  • IDatabaseStrategy: Public Function Save():End Function

  • DataBaseStrategyA:
    Implements IDatabaseStrategy
    Private Function IDataBaseStrategy_Save()
    Debug.Print "Saving to database A"
    End Function
    
  • DataBaseStrategyB:
    Implements IDatabaseStrategy
    Private Function IDataBaseStrategy_Save()
    Debug.Print "Saving to database B"
    End Function
    

Application Module:

Option Explicit

Public Sub ApplicationA()
    Dim Item As IRecord
    Set Item = New Record
    Dim Strategy As IDatabaseStrategy
    Set Strategy = New DatabaseStrategyA
    Item.SetStrategy Strategy 'this would normally be done with constructor
    Dim ItemToSave As IDatabaseStrategy
    Set ItemToSave = Item
    ItemToSave.Save
End Sub

Public Sub ApplicationB()
    Dim Item As IRecord
    Set Item = New Record
    Dim Strategy As IDatabaseStrategy
    Set Strategy = New DatabaseStrategyB
    Item.SetStrategy Strategy 'this would normally be done with constructor
    Dim ItemToSave As IDatabaseStrategy
    Set ItemToSave = Item
    ItemToSave.Save
End Sub

With this approach I have to have Record implement Database strategy to have Save method and then recast Item from IRecord to IDatabaseStrategyto use it. I think I am using the pattern incorrectly, so my question is – how do I provide a DatabaseStrategy to a Record so that I do not have to recast the object and possibly without implementing IDatabaseStrategy in Record?
Alternatives that I have considered:

  • Wrapping DatabaseStrategy around Record specific to the Record and the application (DatabaseStrategy.Create(Record).Save)
  • Exposing DatabaseStrategy as a member of the Record but then it seems that application has to know that DatabaseStrategy is a member of the record (Record.DatabaseStrategy.Save).


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.