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 IDatabaseStrategy
to 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
aroundRecord
specific to theRecord
and the application (DatabaseStrategy.Create(Record).Save
) - Exposing
DatabaseStrategy
as a member of theRecord
but then it seems that application has to know thatDatabaseStrategy
is a member of the record (Record.DatabaseStrategy.Save
).