Friday, May 24, 2013

Implementing Strategy Design Pattern in VBA

In this
post, the main focus is on implementing Strategy Design Pattern. On a
VBA side, we go through the use of VBA interface implementation mechanism.

Interface implementation

Here is a small example on using interface implementation mechanism in
VBA. For this example, you need to insert three new Class Modules and one Standard
module. Follow the instructions given here below.

Insert a
new VBA Standard Module and copy-paste the following code:

Option Explicit

'

Sub tester()

'

' We create an
object which has a type of IInterface

Dim obj As IInterface

'

' Because
ObjectOne implements IInterface, We

' can set this
object to be ObjectOne

Set obj = New ObjectOne

obj.printMessage "Have
a nice day!"

'

' Because
ObjectTwo also implements IInterface, We

' can set this
object to be ObjectTwo

Set obj = New ObjectTwo

obj.printMessage "You
too!"

'

' We release the
object

Set obj = Nothing

EndSub

'

Insert a
new VBA Class Module (name = IInterface) and copy-paste the following code:

Option Explicit

'

' interface to be
implemented

PublicFunction
printMessage(ByVal s AsString)EndFunction

'

Insert a
new VBA Class Module (name = ObjectOne) and copy-paste the following code:

Option Explicit

'

Implements IInterface

'

PrivateFunction
IInterface_printMessage(ByVal s AsString)

Debug.Print "ObjectOne
says " + s

EndFunction

'

Insert a
new VBA Class Module (name = ObjectTwo) and copy-paste the following code:

Option Explicit

'

Implements IInterface

'

PrivateFunction
IInterface_printMessage(ByVal s AsString)

Debug.Print "ObjectTwo
says " + s

EndFunction

'

We are
done. If you run this program, it will print out the following two strings:

ObjectOne
says Have a nice day!

ObjectTwo says You too!

What's
happening here? We create first an interface. After that, we
create two objects, both having the type IInterface because these
objects are implementing IInterface. This means, that we could do the following:

Replace
the existing VBA Standard Module and copy-paste the following code:

If you
run this new main program, it will print out exactly the same two strings as
before:

ObjectOne
says Have a nice day!

ObjectTwo says You too!

However, in this new program we are witnessing
interface-based polymorphism in action. PrintOut function in the previous
code takes object having a type IInterface in its function interface. Since ObjectOne and
ObjectTwo are both IInterface implementations, function accepts the both objects as inputs.

Strategy
design pattern implementation in VBA

Before presenting the actual Strategy Pattern, I would like to present one motivational example, which can help us to understand in a more concrete way, what is the problem what we are trying to solve.

Design - before

Let us
think, that we need to build a program to price a simple forward with the following
requirement:we should be able to price a forward with or without given cashflow PV. How would
you implement this in VBA? Let me present first, how I have been implementing this,
before I got myself familiar with interface implementation.

The
previous program will print out prices for two different forwards. There is
absolutely nothing wrong in this program. However,
as soon as someone wants to add any new requirements for your pricer, you need to modify your ForwardPricer class and Enumerator. All in all, you will end up babysitting Enumerator and Select Case branches, when inserting
any new pricing algorithm, for example.

If we
think about pricing financial instrument, it's all about pricing algorithms which can vary. What if we could create a design, that could
enable the addition of any new algorithm in a such a way, that we do not need to change anything in our existing classes?

Design - after

For this
example, you need to insert four new Class Modules and two Standard modules. Follow
the instructions given here below.

Insert a
new VBA Standard Module and copy-paste the following code. This module is for Enumerator, which is going to be used for implementing parameter wrapper.

Option Explicit

'

PublicEnumVar

Spot

Yieldmaturity

CashflowPV

EndEnum

'

Insert a
new VBA Standard Module and copy-paste the following code. This our tester
program.

The
previous program for pricing 20 forwards with two different pricing algorithms is implementing Strategy Design Pattern. The great thing in this
pattern is, that now if you need to implement any new pricing algorithm, you can just "plug-in" a new interface implementation,
without modifying any existing class. The only requirement is, that any new
implementation must implement everything what the interface has. However, you
are completely free to have any amount of private functions inside your implementations.
In our forward pricing example, any implementation must implement this public
function:

Option Explicit

'

' Interface to be
implemented

PublicFunction
price(ByRef p As
Scripting.Dictionary) AsDouble

EndFunction

'

Constructor problemIn my last posting http://mikejuniperhill.blogspot.fi/2013/05/handling-parameters-dynamically-with.html I was opening up my current approach for having specific input parameters wrapped inside a data structure for allowing maximum flexibility, compared to the approach where you take all specific input parameters in a function interface separately. Now, If we think about that previous forward pricing example, how could we even use that latter approach? Interface public function (price), which we must implement for every implementation, is having a very specific signature for its input parameters. AFAIK, we cannot change that signature in our implementations.

This means, that if we have the following public interface:
Public Function price(ByVal a As Double) As Double

We cannot have the following implementations:
Private Function IForward_price(ByVal a As Double, ByVal c As Double) As Double
Private Function IForward_price(ByVal a As Integer) As Double

If we think this a bit more, why do we have such a problem with this issue after all? Answer: VBA does not have real constructors.For example, in C# you also have interface implementation and any implementation must implement everything, what has been defined in interface. However, there you have constructors for all input parameters and those constructors does not need to have any homogenous signature for input parameters. I wrote the corresponding program in C# (a bit simpler main program) just for the comparison.In this program, instead of feeding parameters inside interface price-method, we can use class constructors in a normal way for feeding required set of parameters to objects. In our VBA implementation, we are doing the same thing by wrapping required set of parameters into a data structure (parameter wrapper) and then feeding that data structure in interface price-method.

The programs, which are presented in this blog, can be freely used, but without warranty or support of any kind. By using the programs presented in this blog, you accept to bear the entire risk, concerning quality or performance of any programs used. In no event, will I be liable to you for the damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the programs presented in this blog. By using the programs presented in this blog, you are accepting the content of this disclaimer.