PowerShell Strategy Pattern

If you have been programming for any length of time, then you may have heard of SOLID design principles. SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible and maintainable. If you are not already following SOLID principles in your development effort, then I highly recommend that you do so as soon as possible.

The one that I want to talk about today is the strategy pattern. The strategy pattern is a software design pattern that enables selecting an algorithm at runtime rather than compile time. Instead of implementing a method directly into a class, the strategy pattern gives you the option to choose what method to use. According to the strategy pattern, the behavior of a class should be encapsulated using interfaces and should not be inherited. This is compatible with the open closed principle, one of the five SOLID rules.

How can you do this in PowerShell? Let me show you! Look at the sample script below.

#  Strategy Pattern Sample Script
class Foo
{
	[bool] CanHandle([int] $value)
	{
		return [bool]($value -eq 1);
	}

	[void] Handle()
	{
		Write-Host('Executing the Handle method on the Foo class.');
	}
}

class Bar
{
	[bool] CanHandle([int] $value)
	{
		return [bool]($value -eq 2);
	}

	[void] Handle()
	{
		Write-Host('Executing the Handle method on the Bar class.');
	}
}

# ─────────────────────────[ Main Method ]─────────────────────────
[object[]] $strategies = @([Foo]::new(), [Bar]::new())
Write-Host $strategies 

[int] $valueToLookFor = 1

$delegate = [Func[object,bool]] {
    $strategyToTest = $args[0];
    return $strategyToTest.CanHandle($valueToLookFor)
}
$strategy = [System.Linq.Enumerable]::SingleOrDefault($strategies, $delegate)
if ($strategy -ne $null) {
    $strategy.Handle()
}

#eof

You can see that I have created two classes Foo and Bar. Now in my example I am just using an integer, but you could use an enumeration value or some other values in the CanHandle method. Once I enter the Main Method of my script, I create an array of strategies. I create a new instance of each class adding it to array as I do so. I then define my delegate method to determine which strategy pattern that I am looking for. You can see that the variable $valueToLookFor has been hard coded for this example. In reality, this is some runtime value that you are looking for. Then I borrow the Single or Default method from .NET’s [System.Linq.Enumerable] class. If a strategy was found that matches, then I execute the Handle method that will perform the work. In a real implementation, you will be passing one or more values to your Handle method.

Hopefully you found this useful and it will allow you to better structure your PowerShell code. I know that the person who needs to maintain your code after you leave will appreciate your efforts. If you enjoyed this post, click those Like and Subscribe buttons. Until next time, Adios Programs!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s