Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Strategy

Overview wikipedia_strategy

The strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.

diagram

Example powershell code

Exist a game that is compatible with two game consoles. We would use strategy pattern to allow change the way of run it depending of target console.

# Strategy
class GameConsole {
    [string] $Name
    hidden [DateTime] $StartTime = [DateTime]::Now

    GameConsole($Name) {
        $this.Name = $Name
    }

    [TimeSpan] GetElapsed(){
        return [DateTime]::Now - $this.StartTime
    }
}

It has been created a GameConsole abstract class and implemented various subclasses to implement the different Game console strategies. Each console has a different way of process a game.

Powershell Classes don’t have support for .NET Abstract classes so this is really just a base class that implements some common logic.

In this case it's defined two strategies for two different game consoles: PlayStation 4 and Xbox One.

# Concrete Strategies
class PlayStation4 : GameConsole {

    Copy () : base('PlayStation4') { }

    Play([Game]$g) {

       # Play game in a PlayStation way
    }
}

class XboxOne : GameConsole {

    Copy () : base('XboxOne') { }

    Play([Game]$g) {

       # Play game in a Xbox One way
    }
}

It should be noted that both have declared a method called Play where each would implement their specific algorithm to process a game.

The Game class have an array with the compatible game consoles and one method called play to run the game in the mentioned game consoles.

# Context
class Game {
    [string] $Name

    hidden [DateTime] $StartTime = [DateTime]::Now
    hidden [Console[]] $GameConsoles = @()

    Game ($Name) {
        $this.Name = $Name
    }

    [TimeSpan] GetElapsed(){
        return [DateTime]::Now - $this.StartTime
    }

    [Game] AddGameConsole([GameConsole]$GC) {
        $this.GameConsoles += $GC

        return $this
    }

    [Game] Play() {
        $this.GameConsoles | ForEach-Object {
            try {
                $_.Play($this)
            }
            catch {
                Write-Host "ERROR:$($_.Exception.Message)")
                break
            }
        }

        return $this
    }

}

Finally, the main code would look like this:

# Main code
[Game]::New("Red Dead Redemption 2").
    AddGameConsole([PlayStation4]::New()).
    AddGameConsole([XboxOne]::New()).
    Play()