Strategy

 Rate It (4)

Strategy

The Strategy design pattern allows you to use multiple algorithms interchangeably. 

One reason you might use a Strategy Pattern is to simplify an overly complex algorithm. Sometimes, as an algorithm evolves to handle more and more situations, it can become very complex and difficult to maintain. Breaking these complex algorithms down into smaller more manageable algorithms might make your code more readable and more easily maintained.  As a simple example of how to implement the Strategy Pattern consider the following scenario.

A software system uses a single authorization checking class to determine access rights within the system.  Access rights will be different for Anonymous users, Logged-In users and System Administrators.

While we could certainly handle these 3 different access levels within a single class, but what if a fourth type of access level were to be added and perhaps a fifth? Let's break out each of the access checks into its own Strategy object that we can use interchangeably based on what type of user is logged into our system.

First, we need to define an Interface that all of our Strategy classes will implement.  It is by implementing this Interface that our Strategy classes will be able to be used interchangeably.

Public Interface IAuthorityCheck

    Function IsAuthorized(ByVal resource As Object) As Boolean

End Interface

With a simple interface defined, we can now create any number of different classes that will implement that interface and perform our security checks for us.  Here are 3 examples that represent our Strategy classes.

First, for our Anonymous users, we create a security Strategy class that always returns False.

Public Class AnonymousSecurityCheckStrategy

    Implements IAuthorityCheck

 

    Public Function IsAuthorized(ByVal resource As Object) As Boolean Implements IAuthorityCheck.IsAuthorized

        'when checking access rights, anonymous users will

        'always be denied access to all resources

        Return False

    End Function

End Class

Next we have our Logged-In users.  They will need a Strategy too to determine their access rights.

Public Class StandardSecurityCheckStrategy

    Implements IAuthorityCheck

 

    Public Function IsAuthorized(ByVal resource As Object) As Boolean Implements IAuthorityCheck.IsAuthorized

        'based on the current users credentials

        'examine the object and determine if the user is allowed to access it

        Dim result As Boolean = PerformSomeApplicationSpecificSecurityChecks(resource)

        Return result

    End Function

End Class

And finally, we have our System Administrators.  They can access everything so they get a Strategy that always returns True.

Public Class SysAdminSecurityCheckStrategy

    Implements IAuthorityCheck

 

    Public Function IsAuthorized(ByVal resource As Object) As Boolean Implements IAuthorityCheck.IsAuthorized

        'The System Administrator will be granted access to all secure resources

        Return True

    End Function

End Class

Now, all we need to do is select one of these Strategy objects at runtime and call the IsAuthorized method.  In order to use these classes interchangeably, we will code against the Interface IAuthorithyCheck and not against that actual concrete class types.

One method for selecting a particular strategy could be to use a Factory.  The Factory would encapsulate all the necessary logic for determining which of our various Strategy classes is the correct one to use.  For example:

Public Class AuthorizationStrategyFactory

    'To avoid the need to repeat the logic required to select the correct Strategy object

    'we will encapsulate that logic in a small Factory class

    Public Shared Function GetAuthorizationStrategy() As IAuthorityCheck

        'This method returns 1 of 3 different algorithms for performing authorizations

 

        'sysadmins gets the Strategy object that always allows access

        If currentUserObject.IsInRole("sysadmin") Then Return New SysAdminSecurityCheckStrategy

 

        If currentUserObject.LoggedIn = True Then

            'Logged in users (non-sysadmin) get a Strategy object that performs various security checks

            Return New StandardSecurityCheckStrategy

        Else

            'All other users are considered Anonymous

            'These users are given a Strategy object that always disallows access

            Return New AnonymousSecurityCheckStrategy

        End If

    End Function

End Class

With the Strategy objects in place and a Factory to create the correct Strategy object for us, it becomes simple to perform the authorization check

'coding against the Interface we created

Dim authorityCheck As IAuthorityCheck

 

'ask the Factory for the Strategy object

authorityCheck = AuthorizationStrategyFactory.GetAuthorizationStrategy()

 

'at this point we have been returned 1 of the 3 strategy objects

'we do not know which one, and we do not need to know which one

 

'perform authorization check

If authorityCheck.IsAuthorized(someResourceObject) = False Then

    'abort - user not authorized

Else

    'proceed - user was authorized

End If

Now if the time comes for a fourth type of access to be needed (JuniorSysAdminEverythingButPayrollAccess), we can create a new Strategy class that implements our Interface and contains the specific algorithm appropriate for the new security check.  Then we would modify the Factory class to return that new Strategy object when it was appropriate to do so.  The last little bit of code that is calling the IsAuthorized method does not need to change at all.

The example here was perhaps a bit contrived, but I hope that it illustrates the mechanics behind implementing the Strategy Pattern.

Also, note that the Provider Model introduced in ASP.NET 2.0 is based on strategy design pattern.

enjoy.

Revision number 5, Thursday, February 21, 2008 10:32:34 AM by
This is not the most up to date version of this article. The most recent version can be found here.

Comments

Shortcuts

Table of Contents

Top Wiki Contributors

Advertise Here

Microsoft Communities
Page view counter